mirror of
https://github.com/immortalwrt/immortalwrt.git
synced 2025-08-07 22:06:25 +08:00
Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@ -231,7 +231,7 @@ menu "Target Images"
|
||||
config GRUB_IMAGES
|
||||
bool "Build GRUB images (Linux x86 or x86_64 host only)"
|
||||
depends on TARGET_x86
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS || TARGET_ROOTFS_EROFS
|
||||
select PACKAGE_grub2
|
||||
select PACKAGE_grub2-bios-setup
|
||||
default y
|
||||
@ -239,7 +239,7 @@ menu "Target Images"
|
||||
config GRUB_EFI_IMAGES
|
||||
bool "Build GRUB EFI images"
|
||||
depends on TARGET_x86 || TARGET_armsr || TARGET_loongarch64
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS || TARGET_ROOTFS_EROFS
|
||||
select PACKAGE_grub2 if TARGET_x86
|
||||
select PACKAGE_grub2-efi if TARGET_x86
|
||||
select PACKAGE_grub2-bios-setup if TARGET_x86
|
||||
|
@ -126,10 +126,12 @@ $(eval $(call SetupHostCommand,diff,Please install GNU diffutils, \
|
||||
diff --version 2>&1 | grep GNU))
|
||||
|
||||
$(eval $(call SetupHostCommand,cp,Please install GNU fileutils, \
|
||||
$(TOPDIR)/staging_dir/host/bin/gcp --help 2>&1 | grep 'Copy SOURCE', \
|
||||
gcp --help 2>&1 | grep 'Copy SOURCE', \
|
||||
cp --help 2>&1 | grep 'Copy SOURCE'))
|
||||
|
||||
$(eval $(call SetupHostCommand,seq,Please install seq, \
|
||||
$(TOPDIR)/staging_dir/host/bin/gseq --version, \
|
||||
gseq --version, \
|
||||
seq --version 2>&1 | grep seq))
|
||||
|
||||
@ -153,10 +155,12 @@ $(eval $(call SetupHostCommand,getopt, \
|
||||
/opt/local/bin/getopt -o t --long test -- --test | grep '^ *--test *--'))
|
||||
|
||||
$(eval $(call SetupHostCommand,realpath,Please install a 'realpath' utility, \
|
||||
$(TOPDIR)/staging_dir/host/bin/grealpath /, \
|
||||
grealpath /, \
|
||||
realpath /))
|
||||
|
||||
$(eval $(call SetupHostCommand,stat,Cannot find a file stat utility, \
|
||||
$(TOPDIR)/staging_dir/host/bin/gstat -c%s $(TOPDIR)/Makefile, \
|
||||
gnustat -c%s $(TOPDIR)/Makefile, \
|
||||
gstat -c%s $(TOPDIR)/Makefile, \
|
||||
stat -c%s $(TOPDIR)/Makefile))
|
||||
@ -175,6 +179,7 @@ $(eval $(call SetupHostCommand,wget,Please install GNU 'wget', \
|
||||
wget --version | grep GNU))
|
||||
|
||||
$(eval $(call SetupHostCommand,install,Please install GNU 'install', \
|
||||
$(TOPDIR)/staging_dir/host/bin/ginstall --version | grep GNU, \
|
||||
install --version | grep GNU, \
|
||||
ginstall --version | grep GNU))
|
||||
|
||||
|
@ -113,7 +113,7 @@ define SetupHostCommand
|
||||
[ -x "$(STAGING_DIR_HOST)/bin/$(strip $(1))" ] && exit 0 \
|
||||
;; \
|
||||
esac; \
|
||||
ln -sf "$$$$$$$$bin" "$(STAGING_DIR_HOST)/bin/$(strip $(1))"; \
|
||||
ln -sf "$$$$$$$${bin#$(STAGING_DIR_HOST)/bin/}" "$(STAGING_DIR_HOST)/bin/$(strip $(1))"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
fi; \
|
||||
|
@ -559,18 +559,6 @@ endef
|
||||
|
||||
$(eval $(call KernelPackage,crypto-kpp))
|
||||
|
||||
define KernelPackage/crypto-lib-aescfb
|
||||
TITLE:=AES cipher operations feedback mode library
|
||||
DEPENDS:=@!LINUX_6_6
|
||||
HIDDEN:=1
|
||||
KCONFIG:=CONFIG_CRYPTO_LIB_AESCFB
|
||||
FILES:=$(LINUX_DIR)/lib/crypto/libaescfb.ko
|
||||
AUTOLOAD:=$(call AutoLoad,09,libaescfb)
|
||||
$(call AddDepends/crypto)
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,crypto-lib-aescfb))
|
||||
|
||||
define KernelPackage/crypto-lib-chacha20
|
||||
TITLE:=ChaCha library interface
|
||||
KCONFIG:=CONFIG_CRYPTO_LIB_CHACHA
|
||||
|
@ -620,7 +620,7 @@ $(eval $(call KernelPackage,drm-imx))
|
||||
define KernelPackage/drm-imx-hdmi
|
||||
SUBMENU:=$(VIDEO_MENU)
|
||||
TITLE:=Freescale i.MX HDMI DRM support
|
||||
DEPENDS:=+kmod-sound-core kmod-drm-imx kmod-drm-display-helper
|
||||
DEPENDS:=+kmod-sound-core kmod-drm-imx +kmod-drm-display-helper
|
||||
KCONFIG:=CONFIG_DRM_IMX_HDMI \
|
||||
CONFIG_DRM_DW_HDMI_AHB_AUDIO \
|
||||
CONFIG_DRM_DW_HDMI_I2S_AUDIO
|
||||
|
@ -8,12 +8,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gettext-full
|
||||
PKG_VERSION:=0.22.5
|
||||
PKG_VERSION:=0.24.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=gettext-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@GNU/gettext
|
||||
PKG_HASH:=fe10c37353213d78a5b83d48af231e005c4da84db5ce88037d88355938259640
|
||||
PKG_HASH:=6164ec7aa61653ac9cdfb41d5c2344563b21f707da1562712e48715f1d2052a6
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/gettext-$(PKG_VERSION)
|
||||
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/gettext-$(PKG_VERSION)
|
||||
|
||||
@ -27,7 +27,7 @@ PKG_BUILD_PARALLEL:=0
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
|
||||
HOST_BUILD_DEPENDS:=gperf/host libiconv-full/host libunistring/host libxml2/host
|
||||
HOST_BUILD_DEPENDS:=gnulib-l10n/host gperf/host libiconv-full/host libunistring/host libxml2/host
|
||||
HOST_BUILD_PARALLEL:=0
|
||||
|
||||
PKG_SUBDIRS:= \
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/autogen.sh
|
||||
+++ b/autogen.sh
|
||||
@@ -81,6 +81,7 @@ if ! $skip_gnulib; then
|
||||
@@ -104,6 +104,7 @@ if ! $skip_gnulib; then
|
||||
getopt-gnu
|
||||
gettext-h
|
||||
havelib
|
||||
@ -18,4 +18,4 @@
|
||||
+LDADD = ../gnulib-lib/libgrt.a $(LTLIBUNISTRING) @LTLIBINTL@ @LTLIBICONV@ $(WOE32_LDADD)
|
||||
|
||||
# Specify installation directory, for --enable-relocatable.
|
||||
gettext_CFLAGS = -DINSTALLDIR=\"$(bindir)\"
|
||||
gettext_CFLAGS = -DINSTALLDIR=$(bindir_c_make)
|
||||
|
37
package/libs/gnulib-l10n/Makefile
Normal file
37
package/libs/gnulib-l10n/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gnulib-l10n
|
||||
PKG_CPE_ID:=cpe:/a:gnu:$(PKG_NAME)
|
||||
PKG_VERSION:=20241231
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@GNU/gnulib
|
||||
PKG_HASH:=155752ba6796aa294cde87c2bf0e771a5891eeeacb131345be0e080a3ec0ceea
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/gnulib-l10n
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=GNU Gnulib localization translation files
|
||||
URL:=http://www.gnu.org/software/gnulib/
|
||||
endef
|
||||
|
||||
define Package/gnulib-l10n/description
|
||||
Localizations (translations) of messages for GNU gnulib code.
|
||||
endef
|
||||
|
||||
HOST_CONFIGURE_ARGS += \
|
||||
--localedir=$(HOST_BUILD_PREFIX)/share/locale
|
||||
|
||||
define Host/Uninstall
|
||||
-$(call Host/Compile/Default,uninstall)
|
||||
endef
|
||||
|
||||
define Package/gnulib-l10n/install
|
||||
$(call Build/Install/Default,install SUBDIRS='$(PKG_SUBDIRS)')
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,gnulib-l10n))
|
@ -17,7 +17,6 @@ PKG_MAINTAINER:=
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_INSTALL:=1
|
||||
|
||||
PKG_BUILD_FLAGS:=lto
|
||||
|
@ -8,8 +8,8 @@ include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=selinux-policy
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://git.defensec.nl/selinux-policy.git
|
||||
PKG_VERSION:=2.6
|
||||
PKG_MIRROR_HASH:=3604ce2d2874f58a7fc03998daa81628fca43aa8ac0a7436f07612365b6ce7ad
|
||||
PKG_VERSION:=2.8.2
|
||||
PKG_MIRROR_HASH:=7e81e6e9e933e6409b7f7bf2d5639960c440c82589c99b199b3540676f88eb8a
|
||||
PKG_SOURCE_VERSION:=v$(PKG_VERSION)
|
||||
PKG_BUILD_DEPENDS:=secilc/host policycoreutils/host
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
From 850a6d031039237b0b13d8fab9f10a7cd4752907 Mon Sep 17 00:00:00 2001
|
||||
From: Dominick Grift <dominick.grift@defensec.nl>
|
||||
Date: Sat, 5 Apr 2025 13:40:26 +0200
|
||||
Subject: [PATCH] loginutils/login.c: libselinux get_default_context() expects
|
||||
seuser
|
||||
|
||||
Use getseuserbyname() to get the seuser associated with username and use that
|
||||
instead with get_default_context()
|
||||
|
||||
>From get_default_context.3:
|
||||
"These functions takes a SELinux user identity that must be defined in the SELinux policy as their input, not a Linux username."
|
||||
|
||||
Fixes: #19075
|
||||
Upstream-Status: Submitted [https://lists.busybox.net/pipermail/busybox/2025-April/091407.html]
|
||||
Signed-off-by: Dominick Grift <dominick.grift@defensec.nl>
|
||||
---
|
||||
loginutils/login.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/loginutils/login.c
|
||||
+++ b/loginutils/login.c
|
||||
@@ -183,12 +183,16 @@ static void die_if_nologin(void)
|
||||
static void initselinux(char *username, char *full_tty,
|
||||
security_context_t *user_sid)
|
||||
{
|
||||
+ char *seuser = NULL, *level = NULL;
|
||||
security_context_t old_tty_sid, new_tty_sid;
|
||||
|
||||
if (!is_selinux_enabled())
|
||||
return;
|
||||
|
||||
- if (get_default_context(username, NULL, user_sid)) {
|
||||
+ if (getseuserbyname(username, &seuser, &level)) {
|
||||
+ bb_error_msg_and_die("can't get seuser for %s", username);
|
||||
+ }
|
||||
+ if (get_default_context(seuser, NULL, user_sid)) {
|
||||
bb_error_msg_and_die("can't get SID for %s", username);
|
||||
}
|
||||
if (getfilecon(full_tty, &old_tty_sid) < 0) {
|
||||
@@ -201,6 +205,11 @@ static void initselinux(char *username,
|
||||
if (setfilecon(full_tty, new_tty_sid) != 0) {
|
||||
bb_perror_msg_and_die("chsid(%s, %s) failed", full_tty, new_tty_sid);
|
||||
}
|
||||
+
|
||||
+ if (ENABLE_FEATURE_CLEAN_UP) {
|
||||
+ free(seuser);
|
||||
+ free(level);
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
@ -163,6 +163,7 @@ sub download
|
||||
my $mirror = shift;
|
||||
my $download_filename = shift;
|
||||
my @additional_mirrors = @_;
|
||||
my @cmd;
|
||||
|
||||
$mirror =~ s!/$!!;
|
||||
|
||||
@ -209,7 +210,11 @@ sub download
|
||||
}
|
||||
};
|
||||
} else {
|
||||
my @cmd = download_cmd("$mirror/$download_filename", $download_filename, @additional_mirrors);
|
||||
if ($mirror =~ /a=snapshot/) {
|
||||
@cmd = download_cmd("$mirror", $download_filename, @additional_mirrors);
|
||||
} else {
|
||||
@cmd = download_cmd("$mirror/$download_filename", $download_filename, @additional_mirrors);
|
||||
}
|
||||
print STDERR "+ ".join(" ",@cmd)."\n";
|
||||
open(FETCH_FD, '-|', @cmd) or die "Cannot launch aria2c, curl or wget.\n";
|
||||
$hash_cmd and do {
|
||||
@ -325,14 +330,23 @@ if (-f "$target/$filename") {
|
||||
|
||||
$download_tool = select_tool();
|
||||
|
||||
my $mirror = shift @mirrors;
|
||||
|
||||
# Try snapshot original source last
|
||||
if ($mirror =~ /snapshot/) {
|
||||
push @mirrors, $mirror;
|
||||
$mirror = shift @mirrors;
|
||||
}
|
||||
|
||||
while (!-f "$target/$filename") {
|
||||
my $mirror = shift @mirrors;
|
||||
$mirror or die "No more mirrors to try - giving up.\n";
|
||||
|
||||
download($mirror, $url_filename, @mirrors);
|
||||
if (!-f "$target/$filename" && $url_filename ne $filename) {
|
||||
download($mirror, $filename, @mirrors);
|
||||
}
|
||||
|
||||
$mirror = shift @mirrors;
|
||||
}
|
||||
|
||||
$SIG{INT} = \&cleanup;
|
||||
|
@ -135,7 +135,7 @@ endef
|
||||
# A reasonable set of default packages handling the NAS type
|
||||
# of devices out of the box (former NAS42x0 IcyBox defaults)
|
||||
GEMINI_NAS_PACKAGES := $(DEFAULT_PACKAGES.nas) \
|
||||
kmod-md-mod kmod-md-linear kmod-md-multipath \
|
||||
kmod-md-mod kmod-md-linear \
|
||||
kmod-md-raid0 kmod-md-raid1 kmod-md-raid10 kmod-md-raid456 \
|
||||
kmod-fs-btrfs kmod-fs-cifs kmod-fs-nfs \
|
||||
kmod-fs-nfsd kmod-fs-ntfs3 kmod-fs-reiserfs kmod-fs-vfat \
|
||||
|
@ -108,6 +108,8 @@
|
||||
pinctrl-0 = <&mdio_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gmac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
@ -367,6 +369,8 @@
|
||||
nvmem-cells = <&eeprom_factory_0>;
|
||||
nvmem-cell-names = "eeprom";
|
||||
status = "okay";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
band@0 {
|
||||
reg = <0>;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <asm/mips-cps.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/smp-ops.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include <mach-rtl83xx.h>
|
||||
|
||||
@ -41,13 +42,13 @@ static void rtlsmp_finish(void)
|
||||
{
|
||||
/* These devices are low on resources. There might be the chance that CEVT_R4K is
|
||||
* not enabled in kernel build. Nevertheless the timer and interrupt 7 might be
|
||||
* active by default after startup of secondary VPE. With no registered handler
|
||||
* that leads to continuous unhandeled interrupts. In this case disable counting
|
||||
* (DC) in the core and confirm a pending interrupt.
|
||||
* active by default after startup of secondary VPEs. With no registered handler
|
||||
* that leads to continuous unhandeled interrupts. Disable it but keep the counter
|
||||
* running so it can still be used as an entropy source.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_CEVT_R4K)) {
|
||||
write_c0_cause(read_c0_cause() | CAUSEF_DC);
|
||||
write_c0_compare(0);
|
||||
write_c0_status(read_c0_status() & ~CAUSEF_IP7);
|
||||
write_c0_compare(read_c0_count() - 1);
|
||||
}
|
||||
|
||||
local_irq_enable();
|
||||
|
@ -29,6 +29,9 @@ extern const struct dsa_switch_ops rtl930x_switch_ops;
|
||||
extern const struct phylink_pcs_ops rtl83xx_pcs_ops;
|
||||
extern const struct phylink_pcs_ops rtl93xx_pcs_ops;
|
||||
|
||||
extern int rtmdio_838x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
|
||||
extern int rtmdio_838x_write_phy(u32 port, u32 page, u32 reg, u32 val);
|
||||
|
||||
DEFINE_MUTEX(smi_lock);
|
||||
|
||||
int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port)
|
||||
@ -244,7 +247,7 @@ int read_phy(u32 port, u32 page, u32 reg, u32 *val)
|
||||
{
|
||||
switch (soc_info.family) {
|
||||
case RTL8380_FAMILY_ID:
|
||||
return rtl838x_read_phy(port, page, reg, val);
|
||||
return rtmdio_838x_read_phy(port, page, reg, val);
|
||||
case RTL8390_FAMILY_ID:
|
||||
return rtl839x_read_phy(port, page, reg, val);
|
||||
case RTL9300_FAMILY_ID:
|
||||
@ -260,7 +263,7 @@ int write_phy(u32 port, u32 page, u32 reg, u32 val)
|
||||
{
|
||||
switch (soc_info.family) {
|
||||
case RTL8380_FAMILY_ID:
|
||||
return rtl838x_write_phy(port, page, reg, val);
|
||||
return rtmdio_838x_write_phy(port, page, reg, val);
|
||||
case RTL8390_FAMILY_ID:
|
||||
return rtl839x_write_phy(port, page, reg, val);
|
||||
case RTL9300_FAMILY_ID:
|
||||
|
@ -340,51 +340,56 @@ static int rtl93xx_get_sds(struct phy_device *phydev)
|
||||
return sds_num;
|
||||
}
|
||||
|
||||
static void rtl83xx_pcs_get_state(struct phylink_pcs *pcs,
|
||||
struct phylink_link_state *state)
|
||||
static void rtldsa_83xx_pcs_get_state(struct phylink_pcs *pcs, struct phylink_link_state *state)
|
||||
{
|
||||
struct rtl838x_pcs *rtpcs = container_of(pcs, struct rtl838x_pcs, pcs);
|
||||
struct rtl838x_switch_priv *priv = rtpcs->priv;
|
||||
int port = rtpcs->port;
|
||||
u64 speed;
|
||||
u64 link;
|
||||
|
||||
if (port < 0 || port > priv->cpu_port) {
|
||||
state->link = false;
|
||||
return;
|
||||
}
|
||||
|
||||
state->link = 0;
|
||||
link = priv->r->get_port_reg_le(priv->r->mac_link_sts);
|
||||
if (link & BIT_ULL(port))
|
||||
state->link = 1;
|
||||
pr_debug("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port));
|
||||
state->speed = SPEED_UNKNOWN;
|
||||
state->duplex = DUPLEX_UNKNOWN;
|
||||
state->pause &= ~(MLO_PAUSE_RX | MLO_PAUSE_TX);
|
||||
|
||||
if (port < 0 || port > priv->cpu_port)
|
||||
return;
|
||||
|
||||
if (!(priv->r->get_port_reg_le(priv->r->mac_link_sts) & BIT_ULL(port)))
|
||||
return;
|
||||
|
||||
state->link = 1;
|
||||
|
||||
state->duplex = 0;
|
||||
if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port))
|
||||
state->duplex = 1;
|
||||
state->duplex = DUPLEX_FULL;
|
||||
else
|
||||
state->duplex = DUPLEX_HALF;
|
||||
|
||||
speed = priv->r->get_port_reg_le(priv->r->mac_link_spd_sts(port));
|
||||
speed >>= (port % 16) << 1;
|
||||
switch (speed & 0x3) {
|
||||
case 0:
|
||||
speed = (speed >> ((port % 16) << 1)) & 0x3;
|
||||
|
||||
switch (speed) {
|
||||
case RTL_SPEED_10:
|
||||
state->speed = SPEED_10;
|
||||
break;
|
||||
case 1:
|
||||
case RTL_SPEED_100:
|
||||
state->speed = SPEED_100;
|
||||
break;
|
||||
case 2:
|
||||
case RTL_SPEED_1000:
|
||||
state->speed = SPEED_1000;
|
||||
break;
|
||||
case 3:
|
||||
if (priv->family_id == RTL9300_FAMILY_ID
|
||||
&& (port == 24 || port == 26)) /* Internal serdes */
|
||||
state->speed = SPEED_2500;
|
||||
else
|
||||
state->speed = SPEED_100; /* Is in fact 500Mbit */
|
||||
/*
|
||||
* This is ok so far but with minor inconsistencies. On RTL838x this setting is
|
||||
* for either 500M or 2G. It might be that MAC_GLITE_STS register tells more. On
|
||||
* RTL839x these vendor specifics are derived from MAC_LINK_500M_STS and mode 3
|
||||
* is 10G. This is of interest so resolve to it. Sadly it is off by one for the
|
||||
* current RTL_SPEED_10000 (=4) definition for RTL93xx.
|
||||
*/
|
||||
state->speed = SPEED_10000;
|
||||
break;
|
||||
}
|
||||
|
||||
state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
|
||||
if (priv->r->get_port_reg_le(priv->r->mac_rx_pause_sts) & BIT_ULL(port))
|
||||
state->pause |= MLO_PAUSE_RX;
|
||||
if (priv->r->get_port_reg_le(priv->r->mac_tx_pause_sts) & BIT_ULL(port))
|
||||
@ -2046,7 +2051,7 @@ static int rtl83xx_dsa_phy_write(struct dsa_switch *ds, int phy_addr, int phy_re
|
||||
|
||||
const struct phylink_pcs_ops rtl83xx_pcs_ops = {
|
||||
.pcs_an_restart = rtl83xx_pcs_an_restart,
|
||||
.pcs_get_state = rtl83xx_pcs_get_state,
|
||||
.pcs_get_state = rtldsa_83xx_pcs_get_state,
|
||||
.pcs_config = rtl83xx_pcs_config,
|
||||
};
|
||||
|
||||
|
@ -1768,169 +1768,6 @@ irqreturn_t rtl838x_switch_irq(int irq, void *dev_id)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int rtl838x_smi_wait_op(int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
ret = readx_poll_timeout(sw_r32, RTL838X_SMI_ACCESS_PHY_CTRL_1,
|
||||
val, !(val & 0x1), 20, timeout);
|
||||
if (ret)
|
||||
pr_err("%s: timeout\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reads a register in a page from the PHY */
|
||||
int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
|
||||
{
|
||||
u32 v, park_page = 0x1f << 15;
|
||||
int err;
|
||||
|
||||
if (port > 31) {
|
||||
*val = 0xffff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (page > 4095 || reg > 31)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mutex_lock(&smi_lock);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
v = reg << 20 | page << 3;
|
||||
sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
*val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&smi_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Write to a register in a page of the PHY */
|
||||
int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
|
||||
{
|
||||
u32 v, park_page = 0x1f << 15;
|
||||
int err;
|
||||
|
||||
val &= 0xffff;
|
||||
if (port > 31 || page > 4095 || reg > 31)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mutex_lock(&smi_lock);
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0);
|
||||
mdelay(10);
|
||||
|
||||
sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
v = reg << 20 | page << 3 | 0x4;
|
||||
sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&smi_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Read an mmd register of a PHY */
|
||||
int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
|
||||
{
|
||||
int err;
|
||||
u32 v;
|
||||
|
||||
mutex_lock(&smi_lock);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
|
||||
mdelay(10);
|
||||
|
||||
sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
v = addr << 16 | reg;
|
||||
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_3);
|
||||
|
||||
/* mmd-access | read | cmd-start */
|
||||
v = 1 << 1 | 0 << 2 | 1;
|
||||
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
*val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&smi_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Write to an mmd register of a PHY */
|
||||
int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
|
||||
{
|
||||
int err;
|
||||
u32 v;
|
||||
|
||||
pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
|
||||
val &= 0xffff;
|
||||
mutex_lock(&smi_lock);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
|
||||
mdelay(10);
|
||||
|
||||
sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
sw_w32_mask(0x1f << 16, addr << 16, RTL838X_SMI_ACCESS_PHY_CTRL_3);
|
||||
sw_w32_mask(0xffff, reg, RTL838X_SMI_ACCESS_PHY_CTRL_3);
|
||||
/* mmd-access | write | cmd-start */
|
||||
v = 1 << 1 | 1 << 2 | 1;
|
||||
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtl838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&smi_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
void rtl8380_get_version(struct rtl838x_switch_priv *priv)
|
||||
{
|
||||
u32 rw_save, info_save;
|
||||
|
@ -27,11 +27,6 @@ extern struct rtl83xx_soc_info soc_info;
|
||||
|
||||
extern int rtl83xx_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data);
|
||||
|
||||
extern int rtl838x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
|
||||
extern int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
|
||||
extern int rtl838x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val);
|
||||
extern int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val);
|
||||
|
||||
extern int rtl839x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val);
|
||||
extern int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
|
||||
extern int rtl839x_read_sds_phy(int phy_addr, int phy_reg);
|
||||
@ -1640,6 +1635,8 @@ static int rtl838x_set_link_ksettings(struct net_device *ndev,
|
||||
* reimplemented. For now it should be sufficient.
|
||||
*/
|
||||
|
||||
DEFINE_MUTEX(rtmdio_lock);
|
||||
|
||||
struct rtmdio_bus_priv {
|
||||
u16 id;
|
||||
u16 family_id;
|
||||
@ -1769,6 +1766,171 @@ static int rtmdio_838x_write_sds(int addr, int regnum, u16 val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* RTL838x specific MDIO functions */
|
||||
|
||||
static int rtmdio_838x_smi_wait_op(int timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 val;
|
||||
|
||||
ret = readx_poll_timeout(sw_r32, RTL838X_SMI_ACCESS_PHY_CTRL_1,
|
||||
val, !(val & 0x1), 20, timeout);
|
||||
if (ret)
|
||||
pr_err("%s: timeout\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reads a register in a page from the PHY */
|
||||
int rtmdio_838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
|
||||
{
|
||||
u32 v, park_page = 0x1f << 15;
|
||||
int err;
|
||||
|
||||
if (port > 31) {
|
||||
*val = 0xffff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (page > 4095 || reg > 31)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mutex_lock(&rtmdio_lock);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
v = reg << 20 | page << 3;
|
||||
sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
*val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&rtmdio_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Write to a register in a page of the PHY */
|
||||
int rtmdio_838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
|
||||
{
|
||||
u32 v, park_page = 0x1f << 15;
|
||||
int err;
|
||||
|
||||
val &= 0xffff;
|
||||
if (port > 31 || page > 4095 || reg > 31)
|
||||
return -ENOTSUPP;
|
||||
|
||||
mutex_lock(&rtmdio_lock);
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0);
|
||||
mdelay(10);
|
||||
|
||||
sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
v = reg << 20 | page << 3 | 0x4;
|
||||
sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&rtmdio_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Read an mmd register of a PHY */
|
||||
static int rtmdio_838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
|
||||
{
|
||||
int err;
|
||||
u32 v;
|
||||
|
||||
mutex_lock(&rtmdio_lock);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
|
||||
mdelay(10);
|
||||
|
||||
sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
v = addr << 16 | reg;
|
||||
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_3);
|
||||
|
||||
/* mmd-access | read | cmd-start */
|
||||
v = 1 << 1 | 0 << 2 | 1;
|
||||
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
*val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&rtmdio_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Write to an mmd register of a PHY */
|
||||
static int rtmdio_838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
|
||||
{
|
||||
int err;
|
||||
u32 v;
|
||||
|
||||
pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
|
||||
val &= 0xffff;
|
||||
mutex_lock(&rtmdio_lock);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
|
||||
mdelay(10);
|
||||
|
||||
sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
|
||||
|
||||
sw_w32_mask(0x1f << 16, addr << 16, RTL838X_SMI_ACCESS_PHY_CTRL_3);
|
||||
sw_w32_mask(0xffff, reg, RTL838X_SMI_ACCESS_PHY_CTRL_3);
|
||||
/* mmd-access | write | cmd-start */
|
||||
v = 1 << 1 | 1 << 2 | 1;
|
||||
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
|
||||
|
||||
err = rtmdio_838x_smi_wait_op(100000);
|
||||
if (err)
|
||||
goto errout;
|
||||
|
||||
err = 0;
|
||||
|
||||
errout:
|
||||
mutex_unlock(&rtmdio_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* These are the core functions of our new Realtek SoC MDIO bus. */
|
||||
|
||||
static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum)
|
||||
@ -2215,10 +2377,10 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
|
||||
priv->mii_bus->read = rtmdio_83xx_read;
|
||||
priv->mii_bus->write = rtmdio_83xx_write;
|
||||
priv->mii_bus->reset = rtmdio_838x_reset;
|
||||
bus_priv->read_mmd_phy = rtl838x_read_mmd_phy;
|
||||
bus_priv->write_mmd_phy = rtl838x_write_mmd_phy;
|
||||
bus_priv->read_phy = rtl838x_read_phy;
|
||||
bus_priv->write_phy = rtl838x_write_phy;
|
||||
bus_priv->read_mmd_phy = rtmdio_838x_read_mmd_phy;
|
||||
bus_priv->write_mmd_phy = rtmdio_838x_write_mmd_phy;
|
||||
bus_priv->read_phy = rtmdio_838x_read_phy;
|
||||
bus_priv->write_phy = rtmdio_838x_write_phy;
|
||||
bus_priv->cpu_port = RTL838X_CPU_PORT;
|
||||
bus_priv->rawpage = 0xfff;
|
||||
break;
|
||||
|
@ -453,4 +453,7 @@ int phy_package_write_paged(struct phy_device *phydev, int page, u32 regnum, u16
|
||||
int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnum);
|
||||
int phy_port_write_paged(struct phy_device *phydev, int port, int page, u32 regnum, u16 val);
|
||||
|
||||
int rtmdio_838x_read_phy(u32 port, u32 page, u32 reg, u32 *val);
|
||||
int rtmdio_838x_write_phy(u32 port, u32 page, u32 reg, u32 val);
|
||||
|
||||
#endif /* _RTL838X_ETH_H */
|
||||
|
@ -98,9 +98,10 @@ $(curdir)/bison/compile := $(curdir)/flex/compile
|
||||
$(curdir)/bzip2/compile := $(curdir)/cmake/compile
|
||||
$(curdir)/cbootimage/compile += $(curdir)/automake/compile
|
||||
$(curdir)/cmake/compile += $(curdir)/libressl/compile $(curdir)/ninja/compile $(curdir)/expat/compile $(curdir)/xz/compile $(curdir)/zlib/compile $(curdir)/zstd/compile
|
||||
$(curdir)/coreutils/compile := $(curdir)/automake/compile $(curdir)/bison/compile $(curdir)/gnulib/compile
|
||||
$(curdir)/dosfstools/compile := $(curdir)/automake/compile
|
||||
$(curdir)/e2fsprogs/compile := $(curdir)/libtool/compile $(curdir)/util-linux/compile
|
||||
$(curdir)/elfutils/compile := $(curdir)/m4/compile $(curdir)/zlib/compile $(curdir)/gnulib/compile $(curdir)/libtool/compile
|
||||
$(curdir)/elfutils/compile := $(curdir)/bison/compile $(curdir)/gnulib/compile $(curdir)/m4/compile $(curdir)/zlib/compile
|
||||
$(curdir)/erofs-utils/compile := $(curdir)/libtool/compile $(curdir)/xz/compile $(curdir)/lz4/compile $(curdir)/util-linux/compile
|
||||
$(curdir)/fakeroot/compile := $(curdir)/libtool/compile
|
||||
$(curdir)/findutils/compile := $(curdir)/bison/compile
|
||||
@ -138,10 +139,17 @@ $(curdir)/util-linux/compile := $(curdir)/bison/compile $(curdir)/automake/compi
|
||||
$(curdir)/yafut/compile := $(curdir)/cmake/compile
|
||||
|
||||
ifneq ($(HOST_OS),Linux)
|
||||
$(curdir)/coreutils/compile += $(curdir)/automake/compile $(curdir)/bison/compile $(curdir)/gnulib/compile
|
||||
$(curdir)/squashfs4/compile += $(curdir)/coreutils/compile
|
||||
tools-y += coreutils
|
||||
else
|
||||
tools-$(if $(CONFIG_BUILD_ALL_HOST_TOOLS)$(CONFIG_SDK),y) += coreutils
|
||||
endif
|
||||
ifneq ($(filter coreutils,$(tools-y)),)
|
||||
$(curdir)/elfutils/compile += $(curdir)/coreutils/compile
|
||||
$(curdir)/findutils/compile += $(curdir)/coreutils/compile
|
||||
$(curdir)/squashfs4/compile += $(curdir)/coreutils/compile
|
||||
$(curdir)/util-linux/compile += $(curdir)/coreutils/compile
|
||||
endif
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
tools-y += bash
|
||||
else
|
||||
|
@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=automake
|
||||
PKG_CPE_ID:=cpe:/a:gnu:automake
|
||||
PKG_VERSION:=1.16.5
|
||||
PKG_VERSION:=1.18.1
|
||||
PKG_API_VERSION:=$(word 2,$(subst ., ,$(PKG_VERSION)))
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@GNU/automake
|
||||
PKG_HASH:=07bd24ad08a64bc17250ce09ec56e921d6343903943e99ccf63bbf0705e34605
|
||||
PKG_HASH:=63e585246d0fc8772dffdee0724f2f988146d1a3f1c756a3dc5cfbefa3c01915
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
@ -21,8 +21,7 @@ HOST_CONFIGURE_ARGS += \
|
||||
--disable-silent-rules
|
||||
|
||||
HOST_CONFIGURE_VARS += \
|
||||
PERL="/usr/bin/env perl" \
|
||||
am_cv_prog_PERL_ithreads=no
|
||||
PERL="/usr/bin/env perl"
|
||||
|
||||
define Host/Configure
|
||||
(cd $(HOST_BUILD_DIR); $(AM_TOOL_PATHS) STAGING_DIR_HOST="" ./bootstrap)
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/lib/Automake/Config.in
|
||||
+++ b/lib/Automake/Config.in
|
||||
@@ -34,7 +34,7 @@ our $PACKAGE = '@PACKAGE@';
|
||||
@@ -32,7 +32,7 @@ our $PACKAGE = '@PACKAGE@';
|
||||
our $PACKAGE_BUGREPORT = '@PACKAGE_BUGREPORT@';
|
||||
our $VERSION = '@VERSION@';
|
||||
our $RELEASE_YEAR = '@RELEASE_YEAR@';
|
||||
@ -11,9 +11,9 @@
|
||||
# We need at least this version for CLONE support.
|
||||
--- a/bin/aclocal.in
|
||||
+++ b/bin/aclocal.in
|
||||
@@ -23,9 +23,11 @@ use 5.006;
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
@@ -21,9 +21,11 @@
|
||||
|
||||
use 5.006; use strict; use warnings;
|
||||
|
||||
+$^W = 1;
|
||||
+
|
||||
@ -24,22 +24,22 @@
|
||||
unless $ENV{AUTOMAKE_UNINSTALLED};
|
||||
}
|
||||
|
||||
@@ -65,8 +67,8 @@ $perl_threads = 0;
|
||||
# ACLOCAL_PATH environment variable, and reset with the '--system-acdir'
|
||||
# option.
|
||||
@@ -63,8 +65,8 @@ $perl_threads = 0;
|
||||
# --aclocal-path option/ACLOCAL_PATH environment variable, and reset
|
||||
# with the '--system-acdir' option.
|
||||
my @user_includes = ();
|
||||
-my @automake_includes = ('@datadir@/aclocal-' . $APIVERSION);
|
||||
-my @system_includes = ('@datadir@/aclocal');
|
||||
+my @automake_includes = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . "/share/aclocal-$APIVERSION" : "@datadir@/aclocal-$APIVERSION");
|
||||
+my @system_includes = ($ENV{'STAGING_DIR_HOST'} ? $ENV{'STAGING_DIR_HOST'} . '/share/aclocal' : '@datadir@/aclocal');
|
||||
my $aclocal_path = '';
|
||||
|
||||
# Whether we should copy M4 file in $user_includes[0].
|
||||
my $install = 0;
|
||||
--- a/bin/automake.in
|
||||
+++ b/bin/automake.in
|
||||
@@ -26,9 +26,11 @@ use 5.006;
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
@@ -24,9 +24,11 @@ package Automake;
|
||||
|
||||
use 5.006; use strict; use warnings;
|
||||
|
||||
+$^W = 1;
|
||||
+
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/bin/aclocal.in
|
||||
+++ b/bin/aclocal.in
|
||||
@@ -371,6 +371,12 @@ sub scan_m4_dirs ($$@)
|
||||
@@ -370,6 +370,12 @@ sub scan_m4_dirs ($$@)
|
||||
|
||||
foreach my $m4dir (@dirlist)
|
||||
{
|
||||
|
@ -1,15 +1,6 @@
|
||||
--- a/bin/automake.in
|
||||
+++ b/bin/automake.in
|
||||
@@ -4513,7 +4513,7 @@ sub handle_gettext ()
|
||||
&& grep ($_ eq 'intl', @subdirs));
|
||||
}
|
||||
|
||||
- require_file ($ac_gettext_location, GNU, 'ABOUT-NLS');
|
||||
+ require_file ($ac_gettext_location, GNITS, 'ABOUT-NLS');
|
||||
}
|
||||
|
||||
# Emit makefile footer.
|
||||
@@ -5641,7 +5641,7 @@ sub check_gnu_standards ()
|
||||
@@ -5700,7 +5700,7 @@ sub check_gnu_standards ()
|
||||
# otherwise require non-.md.
|
||||
my $required
|
||||
= (! -f $file && -f "$file.md") ? "$file.md" : $file;
|
||||
@ -18,7 +9,7 @@
|
||||
}
|
||||
|
||||
# Accept one of these three licenses; default to COPYING.
|
||||
@@ -5655,7 +5655,7 @@ sub check_gnu_standards ()
|
||||
@@ -5714,7 +5714,7 @@ sub check_gnu_standards ()
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ Subject: [PATCH] Allow other V values for verbosity
|
||||
|
||||
--- a/m4/silent.m4
|
||||
+++ b/m4/silent.m4
|
||||
@@ -43,7 +43,7 @@ else
|
||||
fi])
|
||||
@@ -53,7 +53,7 @@ case $enable_silent_rules in @%:@ (((
|
||||
esac
|
||||
if test $am_cv_make_support_nested_variables = yes; then
|
||||
dnl Using '$V' instead of '$(V)' breaks IRIX make.
|
||||
- AM_V='$(V)'
|
||||
|
34
tools/automake/patches/300-output-TRUE-cond-first.patch
Normal file
34
tools/automake/patches/300-output-TRUE-cond-first.patch
Normal file
@ -0,0 +1,34 @@
|
||||
--- a/lib/Automake/Variable.pm
|
||||
+++ b/lib/Automake/Variable.pm
|
||||
@@ -1258,8 +1258,15 @@ sub output_variables ()
|
||||
foreach my $var (@vars)
|
||||
{
|
||||
my $v = rvar $var;
|
||||
+ # Output unconditional definitions before conditional ones.
|
||||
+ if ($v->def (TRUE)) {
|
||||
+ $res .= $v->output (TRUE)
|
||||
+ if $v->rdef (TRUE)->owner == VAR_AUTOMAKE;
|
||||
+ }
|
||||
foreach my $cond ($v->conditions->conds)
|
||||
{
|
||||
+ # TRUE is handled already.
|
||||
+ next if $cond->string eq "TRUE";
|
||||
$res .= $v->output ($cond)
|
||||
if $v->rdef ($cond)->owner == VAR_AUTOMAKE;
|
||||
}
|
||||
@@ -1269,8 +1276,15 @@ sub output_variables ()
|
||||
foreach my $var (@vars)
|
||||
{
|
||||
my $v = rvar $var;
|
||||
+ # Output unconditional definitions before conditional ones.
|
||||
+ if ($v->def (TRUE)) {
|
||||
+ $res .= $v->output (TRUE)
|
||||
+ if $v->rdef (TRUE)->owner != VAR_AUTOMAKE;
|
||||
+ }
|
||||
foreach my $cond ($v->conditions->conds)
|
||||
{
|
||||
+ # TRUE is handled already.
|
||||
+ next if $cond->string eq "TRUE";
|
||||
$res .= $v->output ($cond)
|
||||
if $v->rdef ($cond)->owner != VAR_AUTOMAKE;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
--- a/bin/automake.in
|
||||
+++ b/bin/automake.in
|
||||
@@ -4760,12 +4760,42 @@ sub handle_clean
|
||||
if var ('CLEANFILES');
|
||||
$clean_files{'$(DISTCLEANFILES)'} = DIST_CLEAN
|
||||
if var ('DISTCLEANFILES');
|
||||
- $clean_files{'$(MAINTAINERCLEANFILES)'} = MAINTAINER_CLEAN
|
||||
- if var ('MAINTAINERCLEANFILES');
|
||||
|
||||
# Built sources are automatically removed by maintainer-clean.
|
||||
- $clean_files{'$(BUILT_SOURCES)'} = MAINTAINER_CLEAN
|
||||
- if var ('BUILT_SOURCES');
|
||||
+ # For each defined condition of the maintainer-clean variable, append built sources
|
||||
+ # and create an unconditional definition with built sources if not already defined.
|
||||
+ # Then, for each definition of built sources without maintainer-clean defined, define it.
|
||||
+ # Otherwise, if the variable is not user-defined, define it with built sources.
|
||||
+ my $mcleanvar = var ('MAINTAINERCLEANFILES');
|
||||
+ if ($mcleanvar) {
|
||||
+ foreach my $rcond ($mcleanvar->conditions->conds)
|
||||
+ {
|
||||
+ if (! grep { $_ eq '$(BUILT_SOURCES)' } $mcleanvar->value_as_list ($rcond)) {
|
||||
+ Automake::Variable::define ($mcleanvar->name, VAR_MAKEFILE, '+', $rcond,
|
||||
+ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS)
|
||||
+ if vardef ('BUILT_SOURCES', $rcond);
|
||||
+ }
|
||||
+ }
|
||||
+ my $bsources = var ('BUILT_SOURCES');
|
||||
+ if ($bsources) {
|
||||
+ foreach my $rcond ($bsources->conditions->conds)
|
||||
+ {
|
||||
+ Automake::Variable::define ($mcleanvar->name, VAR_MAKEFILE, '', $rcond,
|
||||
+ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS)
|
||||
+ if ! vardef ($mcleanvar, $rcond);
|
||||
+ }
|
||||
+ if (! vardef ($mcleanvar, TRUE)) {
|
||||
+ Automake::Variable::define ($mcleanvar->name, VAR_MAKEFILE, '', TRUE,
|
||||
+ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ Automake::Variable::define ('MAINTAINERCLEANFILES', VAR_MAKEFILE, '', TRUE,
|
||||
+ '$(BUILT_SOURCES)', '', INTERNAL, VAR_ASIS)
|
||||
+ if var ('BUILT_SOURCES');
|
||||
+ }
|
||||
+ $clean_files{'$(MAINTAINERCLEANFILES)'} = MAINTAINER_CLEAN
|
||||
+ if var ('MAINTAINERCLEANFILES');
|
||||
|
||||
# Compute a list of "rm"s to run for each target.
|
||||
my %rms = (MOSTLY_CLEAN, [],
|
28
tools/automake/patches/999-clean-am.patch
Normal file
28
tools/automake/patches/999-clean-am.patch
Normal file
@ -0,0 +1,28 @@
|
||||
--- a/lib/am/clean.am
|
||||
+++ b/lib/am/clean.am
|
||||
@@ -39,7 +39,7 @@ distclean-generic:
|
||||
## If you change distclean here, you probably also want to change
|
||||
## maintainer-clean below.
|
||||
distclean:
|
||||
- -rm -f %MAKEFILE%
|
||||
+ -touch %MAKEFILE%
|
||||
|
||||
maintainer-clean-am: maintainer-clean-generic distclean-am
|
||||
maintainer-clean-generic:
|
||||
@@ -51,7 +51,7 @@ maintainer-clean-generic:
|
||||
|
||||
## See comment for distclean.
|
||||
maintainer-clean:
|
||||
- -rm -f %MAKEFILE%
|
||||
+ -touch %MAKEFILE%
|
||||
|
||||
.PHONY: clean mostlyclean distclean maintainer-clean \
|
||||
clean-generic mostlyclean-generic distclean-generic maintainer-clean-generic
|
||||
--- a/lib/am/libtool.am
|
||||
+++ b/lib/am/libtool.am
|
||||
@@ -25,4 +25,4 @@ clean-libtool:
|
||||
|
||||
?TOPDIR_P?distclean-am: distclean-libtool
|
||||
?TOPDIR_P?distclean-libtool:
|
||||
-?TOPDIR_P? -rm -f libtool config.lt
|
||||
+?TOPDIR_P? -touch libtool config.lt
|
@ -13,13 +13,14 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@GNU/bc
|
||||
PKG_HASH:=515430115b3334c636317503460a0950dff79940aa3259ce2c1aa67c2881d023
|
||||
|
||||
PKG_FIXUP := autoreconf
|
||||
PKG_CPE_ID:=cpe:/a:gnu:bc
|
||||
|
||||
PKG_SUBDIRS:=lib bc dc
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
define Host/Uninstall
|
||||
-$(call Host/Compile/Default,uninstall)
|
||||
-$(call Host/Compile/Default,uninstall SUBDIRS='lib bc dc')
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
|
18
tools/bc/patches/000-getopt-prototype.patch
Normal file
18
tools/bc/patches/000-getopt-prototype.patch
Normal file
@ -0,0 +1,18 @@
|
||||
--- a/h/getopt.h
|
||||
+++ b/h/getopt.h
|
||||
@@ -135,15 +135,7 @@ struct option
|
||||
arguments to the option '\0'. This behavior is specific to the GNU
|
||||
`getopt'. */
|
||||
|
||||
-#ifdef __GNU_LIBRARY__
|
||||
-/* Many other libraries have conflicting prototypes for getopt, with
|
||||
- differences in the consts, in stdlib.h. To avoid compilation
|
||||
- errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
|
||||
-#else /* not __GNU_LIBRARY__ */
|
||||
-extern int getopt ();
|
||||
-#endif /* __GNU_LIBRARY__ */
|
||||
-
|
||||
#ifndef __need_getopt
|
||||
extern int getopt_long (int ___argc, char *const *___argv,
|
||||
const char *__shortopts,
|
@ -1,21 +0,0 @@
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1,6 +1,6 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
-SUBDIRS = lib bc dc doc
|
||||
+SUBDIRS = lib bc dc
|
||||
|
||||
MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
|
||||
stamp-h $(distdir).tar.gz h/number.h depcomp missing
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -305,7 +305,7 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
-SUBDIRS = lib bc dc doc
|
||||
+SUBDIRS = lib bc dc
|
||||
MAINTAINERCLEANFILES = aclocal.m4 config.h.in configure Makefile.in \
|
||||
stamp-h $(distdir).tar.gz h/number.h depcomp missing
|
||||
|
@ -1,11 +0,0 @@
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -5926,7 +5926,7 @@ case $bcle-$bcrl-$LEX in
|
||||
?-?-flex)
|
||||
LEX="flex -I -8" ;;
|
||||
?-y-*)
|
||||
- as_fn_error $? "readline works only with flex." "$LINENO" 5 ;;
|
||||
+ : ;; # as_fn_error $? "readline works only with flex." "$LINENO" 5 ;;
|
||||
esac
|
||||
|
||||
case $LEX-`uname -s` in
|
@ -8,38 +8,42 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=coreutils
|
||||
PKG_CPE_ID:=cpe:/a:gnu:coreutils
|
||||
PKG_VERSION:=9.5
|
||||
PKG_VERSION:=9.6
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@GNU/coreutils
|
||||
PKG_HASH:=767ae6a22950ec42f3ba5f7c1de79dd27800ee8e9b8642da5dedb5974a1741e5
|
||||
PKG_HASH:=2bec616375002c92c1ed5ead32a092b174fe44c14bc736d32e5961053b821d84
|
||||
|
||||
HOST_BUILD_PARALLEL := 1
|
||||
|
||||
PKG_PROGRAMS:=date readlink touch ln chown ginstall
|
||||
PKG_PROGRAMS:=chown cp date ginstall ln readlink realpath rmdir seq stat touch
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
export GNULIB_SRCDIR:=$(HOST_GNULIB_SRCDIR)
|
||||
|
||||
HOST_GNULIB_SKIP := \
|
||||
lib/nstrftime.c \
|
||||
lib/fprintftime.c \
|
||||
lib/fcntl.in.h \
|
||||
lib/locale.in.h
|
||||
lib/iconv_open-aix.gperf \
|
||||
lib/iconv_open-hpux.gperf \
|
||||
lib/iconv_open-irix.gperf \
|
||||
lib/iconv_open-osf.gperf \
|
||||
lib/iconv_open-solaris.gperf \
|
||||
lib/iconv_open-zos.gperf
|
||||
|
||||
HOST_CONFIGURE_ARGS += \
|
||||
--enable-install-program=$(subst $(space),$(comma),$(strip $(PKG_PROGRAMS)))
|
||||
|
||||
HOST_MAKE_FLAGS += \
|
||||
$(AM_TOOL_PATHS_FAKE) \
|
||||
$(AM_TOOL_PATHS) AUTOPOINT="$(TRUE)" GTKDOCIZE="$(TRUE)" \
|
||||
am__CONFIG_DISTCLEAN_FILES= \
|
||||
MAINTAINERCLEANFILES='$$$$(filter-out lib/iconv_open% %.texi,$$$$(BUILT_SOURCES))' \
|
||||
PROGRAMS="$(patsubst %,src/%,$(PKG_PROGRAMS))" \
|
||||
LIBRARIES= MANS= SUBDIRS=.
|
||||
|
||||
define Host/Bootstrap
|
||||
( \
|
||||
cd $(HOST_BUILD_DIR); \
|
||||
$(AM_TOOL_PATHS_FAKE) \
|
||||
$(AM_TOOL_PATHS) AUTOPOINT="$(TRUE)" GTKDOCIZE="$(TRUE)" \
|
||||
./bootstrap \
|
||||
--bootstrap-sync \
|
||||
--force \
|
||||
@ -58,17 +62,21 @@ define Host/Configure
|
||||
$(if $(QUILT),$(call Host/Bootstrap))
|
||||
$(foreach src,$(HOST_GNULIB_SKIP),mv -f $(HOST_BUILD_DIR)/$(src)~ $(HOST_BUILD_DIR)/$(src) || true; )
|
||||
$(call Host/Configure/Default)
|
||||
$(call Host/Uninstall)
|
||||
$(call Host/Compile/Default,lib/config.h)
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(INSTALL_DIR) $(1)/bin
|
||||
$(INSTALL_BIN) $(patsubst %,$(HOST_BUILD_DIR)/src/%,$(PKG_PROGRAMS)) $(1)/bin/
|
||||
ln -sf ginstall $(1)/bin/install
|
||||
$(foreach prog,$(filter-out g%,$(PKG_PROGRAMS)),$(INSTALL_BIN) $(patsubst %,$(HOST_BUILD_DIR)/src/%,$(prog)) $(1)/bin/g$(prog); )
|
||||
$(foreach prog,$(filter g%,$(PKG_PROGRAMS)),$(INSTALL_BIN) $(patsubst %,$(HOST_BUILD_DIR)/src/%,$(prog)) $(1)/bin/$(prog); )
|
||||
$(foreach prog,$(filter-out g%,$(PKG_PROGRAMS)),g$(LN) g$(prog) $(1)/bin/$(prog); )
|
||||
$(foreach prog,$(filter g%,$(PKG_PROGRAMS)),g$(LN) $(prog) $(1)/bin/$(patsubst g%,%,$(prog)); )
|
||||
endef
|
||||
|
||||
define Host/Uninstall
|
||||
rm -f $(STAGING_DIR_HOST)/bin/install
|
||||
-$(call Host/Compile/Default,uninstall)
|
||||
#$(call Host/Compile/Default,uninstall) # Removes necessary symlinks
|
||||
-$(call Host/Compile/Default,maintainer-clean) # Clean bootstrap files from the release
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
|
@ -34,7 +34,7 @@
|
||||
if [ ! "$inst_ver" ]; then
|
||||
warn_ "Error: '$app' not found"
|
||||
ret=1
|
||||
@@ -1157,7 +1157,7 @@ autogen()
|
||||
@@ -1205,7 +1205,7 @@ autogen()
|
||||
# two just-pre-run programs.
|
||||
|
||||
# Import from gettext.
|
||||
@ -43,3 +43,17 @@
|
||||
grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
|
||||
with_gettext=no
|
||||
|
||||
--- a/bootstrap.conf
|
||||
+++ b/bootstrap.conf
|
||||
@@ -354,11 +354,8 @@ gnulib_tool_option_extras="--tests-base=
|
||||
buildreq="\
|
||||
autoconf 2.64
|
||||
automake 1.11.2
|
||||
-autopoint 0.19.2
|
||||
bison -
|
||||
-gettext 0.19.2
|
||||
git 1.4.4
|
||||
-gperf -
|
||||
gzip -
|
||||
m4 -
|
||||
makeinfo 6.1
|
||||
|
@ -3,12 +3,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=elfutils
|
||||
PKG_VERSION:=0.191
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=0.192
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=https://sourceware.org/$(PKG_NAME)/ftp/$(PKG_VERSION)
|
||||
PKG_HASH:=df76db71366d1d708365fc7a6c60ca48398f14367eb2b8954efc8897147ad871
|
||||
PKG_HASH:=616099beae24aba11f9b63d86ca6cc8d566d968b802391334c91df54eab416b4
|
||||
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
PKG_LICENSE_FILES:=COPYING COPYING-GPLV2 COPYING-LGPLV3
|
||||
@ -43,24 +43,49 @@ PKG_GNULIB_MODS = \
|
||||
fallocate-posix \
|
||||
fnmatch-gnu \
|
||||
fts \
|
||||
obstack \
|
||||
obstack-printf-posix \
|
||||
progname \
|
||||
strchrnul \
|
||||
tsearch
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
export $(PKG_GNULIB_BASE)=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/.libs/$(PKG_GNULIB_BASE).a
|
||||
|
||||
export $(PKG_GNULIB_BASE)_exitfail=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-exitfail.o
|
||||
export $(PKG_GNULIB_BASE)_fallocate-posix=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-posix_fallocate.o
|
||||
export $(PKG_GNULIB_BASE)_mbszero=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-mbszero.o
|
||||
export $(PKG_GNULIB_BASE)_obstack=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-obstack.o
|
||||
export $(PKG_GNULIB_BASE)_obstack-printf=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-obstack_printf.o
|
||||
export $(PKG_GNULIB_BASE)_printf-args=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-args.o
|
||||
export $(PKG_GNULIB_BASE)_printf-frexp=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-frexp.o
|
||||
export $(PKG_GNULIB_BASE)_printf-frexpl=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-frexpl.o
|
||||
export $(PKG_GNULIB_BASE)_printf-parse=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-printf-parse.o
|
||||
export $(PKG_GNULIB_BASE)_tsearch=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-tsearch.o
|
||||
export $(PKG_GNULIB_BASE)_vasnprintf=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-vasnprintf.o
|
||||
export $(PKG_GNULIB_BASE)_xsize=$(HOST_BUILD_DIR)/$(PKG_GNULIB_BASE)/$(PKG_GNULIB_BASE)_la-xsize.o
|
||||
|
||||
HOST_MAKE_FLAGS += \
|
||||
DEFAULT_INCLUDES='-I. -I$$$$(top_builddir) -I$$$$(top_srcdir)/$(PKG_GNULIB_BASE)' \
|
||||
am__CONFIG_DISTCLEAN_FILES= \
|
||||
DEFAULT_INCLUDES='-iquote . -I$$$$(top_builddir) -I$$$$(top_srcdir)/$(PKG_GNULIB_BASE)' \
|
||||
AM_LDFLAGS='$$$$(STACK_USAGE_NO_ERROR)' \
|
||||
LIBS+='$$$$(if $$$$(findstring $(lastword $(PKG_SUBDIRS)),$$$$(subdir)), $$$$($(PKG_GNULIB_BASE)))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_exitfail))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_fallocate-posix))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_mbszero))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_obstack))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_obstack-printf))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-args))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-frexp))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-frexpl))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_printf-parse))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_tsearch))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_vasnprintf))' \
|
||||
LIBS+='$$$$(wildcard $$$$($(PKG_GNULIB_BASE)_xsize))' \
|
||||
REPLACE_FCNTL=0 REPLACE_FREE=0 REPLACE_FSTAT=0 REPLACE_OPEN=0 \
|
||||
REPLACE_OBSTACK=0 REPLACE_OBSTACK_PRINTF=0 \
|
||||
bin_PROGRAMS='$(PKG_PROGRAMS)' EXEEXT=
|
||||
|
||||
HOST_CPPFLAGS += "'-I$$$$(top_srcdir)/lib'"
|
||||
@ -72,6 +97,7 @@ endif
|
||||
HOST_CFLAGS += -Wno-error -fPIC -std=gnu17
|
||||
|
||||
HOST_CONFIGURE_ARGS += \
|
||||
--enable-maintainer-mode \
|
||||
--without-libintl-prefix \
|
||||
--without-libiconv-prefix \
|
||||
--disable-debuginfod \
|
||||
@ -96,8 +122,14 @@ HOST_CONFIGURE_VARS += \
|
||||
Hooks/HostConfigure/Pre := Host/Gnulib/Prepare $(Hooks/HostConfigure/Pre)
|
||||
Hooks/HostCompile/Pre := Host/Gnulib/Compile $(Hooks/HostCompile/Pre)
|
||||
|
||||
define Host/Configure
|
||||
$(call Host/Configure/Default)
|
||||
$(call Host/Uninstall)
|
||||
endef
|
||||
|
||||
define Host/Uninstall
|
||||
-$(call Host/Compile/Default,uninstall)
|
||||
-$(call Host/Compile/Default,maintainer-clean) # Clean bootstrap files from the release
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
|
12
tools/elfutils/patches/001-fix-backport-iquote-include.patch
Normal file
12
tools/elfutils/patches/001-fix-backport-iquote-include.patch
Normal file
@ -0,0 +1,12 @@
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -21,7 +21,8 @@ DEFS += $(YYDEBUG) -DDEBUGPRED=@DEBUGPRE
|
||||
-DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\"
|
||||
|
||||
DEFAULT_INCLUDES =
|
||||
-AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
|
||||
+AM_CPPFLAGS = -iquote . -iquote $(srcdir) -I$(top_srcdir)/lib \
|
||||
+ -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
|
||||
-I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \
|
||||
-I$(srcdir)/../libdwfl -I$(srcdir)/../libasm -I../debuginfod
|
||||
|
File diff suppressed because it is too large
Load Diff
230
tools/elfutils/patches/011-backport-mips-support-strip.patch
Normal file
230
tools/elfutils/patches/011-backport-mips-support-strip.patch
Normal file
@ -0,0 +1,230 @@
|
||||
In mips64 little-endian, r_info consists of four byte fields(contains
|
||||
three reloc types) and a 32-bit symbol index. In order to adapt
|
||||
GELF_R_SYM and GELF_R_TYPE, need convert raw data to get correct symbol
|
||||
index and type.
|
||||
|
||||
libelf/elf_getdata.c: Some eu-utils use read-mmap method to map file,
|
||||
so we need to malloc and memcpy raw data to avoid segment fault. After
|
||||
modification, the correct value are saved in the malloced memory not in
|
||||
process address space.
|
||||
libelf/elf_updata.c: Because we converted the relocation info in mips
|
||||
order when we call elf_getdata.c, so we need to convert the modified data
|
||||
in original order bits before writing the data to the file.
|
||||
|
||||
Signed-off-by: Ying Huang <ying.huang@oss.cipunited.com>
|
||||
---
|
||||
libelf/elf_getdata.c | 132 ++++++++++++++++++++++++++++++++++++++++++-
|
||||
libelf/elf_update.c | 53 +++++++++++++++++
|
||||
2 files changed, 183 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/libelf/elf_getdata.c
|
||||
+++ b/libelf/elf_getdata.c
|
||||
@@ -135,6 +135,119 @@ __libelf_data_type (GElf_Ehdr *ehdr, int
|
||||
|
||||
/* Convert the data in the current section. */
|
||||
static void
|
||||
+convert_data_for_mips64el (Elf_Scn *scn, int eclass,
|
||||
+ int data, size_t size, Elf_Type type)
|
||||
+{
|
||||
+ /* Do we need to convert the data and/or adjust for alignment? */
|
||||
+ if (data == MY_ELFDATA || type == ELF_T_BYTE)
|
||||
+ {
|
||||
+ /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
|
||||
+ relocation info(raw data). Some eu-utils use read-mmap method to map file, so
|
||||
+ we need to malloc and memcpy raw data to avoid segment fault. After modification,
|
||||
+ the correct value are saved in the malloced memory not in process address space. */
|
||||
+ scn->data_base = malloc (size);
|
||||
+ if (scn->data_base == NULL)
|
||||
+ {
|
||||
+ __libelf_seterrno (ELF_E_NOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* The copy will be appropriately aligned for direct access. */
|
||||
+ memcpy (scn->data_base, scn->rawdata_base, size);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ xfct_t fp;
|
||||
+
|
||||
+ scn->data_base = malloc (size);
|
||||
+ if (scn->data_base == NULL)
|
||||
+ {
|
||||
+ __libelf_seterrno (ELF_E_NOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Make sure the source is correctly aligned for the conversion
|
||||
+ function to directly access the data elements. */
|
||||
+ char *rawdata_source;
|
||||
+ /* In order to adapt macro GELF_R_SYM and GELF_R_TYPE on mips64, need to convert
|
||||
+ relocation info(raw data). Some eu-utils use read-mmap method to map file, so
|
||||
+ we need to malloc and memcpy raw data to avoid segment fault. After modification,
|
||||
+ the correct value are saved in the malloced memory not in process address space. */
|
||||
+ rawdata_source = malloc (size);
|
||||
+ if (rawdata_source == NULL)
|
||||
+ {
|
||||
+ __libelf_seterrno (ELF_E_NOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* The copy will be appropriately aligned for direct access. */
|
||||
+ memcpy (rawdata_source, scn->rawdata_base, size);
|
||||
+
|
||||
+ /* Get the conversion function. */
|
||||
+ fp = __elf_xfctstom[eclass - 1][type];
|
||||
+
|
||||
+ fp (scn->data_base, rawdata_source, size, 0);
|
||||
+
|
||||
+ if (rawdata_source != scn->rawdata_base)
|
||||
+ free (rawdata_source);
|
||||
+ }
|
||||
+
|
||||
+ scn->data_list.data.d.d_buf = scn->data_base;
|
||||
+ scn->data_list.data.d.d_size = size;
|
||||
+ scn->data_list.data.d.d_type = type;
|
||||
+ scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
|
||||
+ scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
|
||||
+ scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
|
||||
+
|
||||
+ scn->data_list.data.s = scn;
|
||||
+
|
||||
+ /* In mips64 little-endian, r_info consists of four byte fields(contains
|
||||
+ three reloc types) and a 32-bit symbol index. In order to adapt
|
||||
+ GELF_R_SYM and GELF_R_TYPE, need to convert r_info to get correct symbol
|
||||
+ index and type. */
|
||||
+ /* references:
|
||||
+ https://www.linux-mips.org/pub/linux/mips/doc/ABI/elf64-2.4.pdf
|
||||
+ Page40 && Page41 */
|
||||
+ GElf_Shdr shdr_mem;
|
||||
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
+ if (shdr->sh_type == SHT_REL)
|
||||
+ {
|
||||
+ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
|
||||
+ int nentries = shdr->sh_size / sh_entsize;
|
||||
+ for (int cnt = 0; cnt < nentries; ++cnt)
|
||||
+ {
|
||||
+ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
|
||||
+ Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
|
||||
+ Elf64_Xword info = value->r_info;
|
||||
+ value->r_info = (((info & 0xffffffff) << 32)
|
||||
+ | ((info >> 56) & 0xff)
|
||||
+ | ((info >> 40) & 0xff00)
|
||||
+ | ((info >> 24) & 0xff0000)
|
||||
+ | ((info >> 8) & 0xff000000));
|
||||
+ ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (shdr->sh_type == SHT_RELA)
|
||||
+ {
|
||||
+ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
|
||||
+ int nentries = shdr->sh_size / sh_entsize;
|
||||
+ for (int cnt = 0; cnt < nentries; cnt++)
|
||||
+ {
|
||||
+ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) &scn->data_list.data.d;
|
||||
+ Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
|
||||
+ Elf64_Xword info = value->r_info;
|
||||
+ value->r_info = (((info & 0xffffffff) << 32)
|
||||
+ | ((info >> 56) & 0xff)
|
||||
+ | ((info >> 40) & 0xff00)
|
||||
+ | ((info >> 24) & 0xff0000)
|
||||
+ | ((info >> 8) & 0xff000000));
|
||||
+ ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Convert the data in the current section. */
|
||||
+static void
|
||||
convert_data (Elf_Scn *scn, int eclass,
|
||||
int data, size_t size, Elf_Type type)
|
||||
{
|
||||
@@ -451,8 +564,23 @@ __libelf_set_data_list_rdlock (Elf_Scn *
|
||||
return;
|
||||
}
|
||||
|
||||
- /* Convert according to the version and the type. */
|
||||
- convert_data (scn, elf->class,
|
||||
+ GElf_Shdr shdr_mem;
|
||||
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
+ GElf_Ehdr ehdr_mem;
|
||||
+ GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
|
||||
+ if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
|
||||
+ scn->elf->class == ELFCLASS64 && ehdr != NULL &&
|
||||
+ ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
|
||||
+ convert_data_for_mips64el (scn, elf->class,
|
||||
+ (elf->class == ELFCLASS32
|
||||
+ || (offsetof (struct Elf, state.elf32.ehdr)
|
||||
+ == offsetof (struct Elf, state.elf64.ehdr))
|
||||
+ ? elf->state.elf32.ehdr->e_ident[EI_DATA]
|
||||
+ : elf->state.elf64.ehdr->e_ident[EI_DATA]),
|
||||
+ scn->rawdata.d.d_size, scn->rawdata.d.d_type);
|
||||
+ else
|
||||
+ /* Convert according to the version and the type. */
|
||||
+ convert_data (scn, elf->class,
|
||||
(elf->class == ELFCLASS32
|
||||
|| (offsetof (struct Elf, state.elf32.ehdr)
|
||||
== offsetof (struct Elf, state.elf64.ehdr))
|
||||
--- a/libelf/elf_update.c
|
||||
+++ b/libelf/elf_update.c
|
||||
@@ -228,7 +228,60 @@ elf_update (Elf *elf, Elf_Cmd cmd)
|
||||
size = -1;
|
||||
}
|
||||
else
|
||||
+ {
|
||||
+ /* Because we converted the relocation info in mips order when we call elf_getdata.c,
|
||||
+ so we need to convert the modified data in original order bits before writing the
|
||||
+ data to the file. */
|
||||
+ Elf_Scn *scn = NULL;
|
||||
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
|
||||
+ {
|
||||
+ GElf_Shdr shdr_mem;
|
||||
+ GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
||||
+ GElf_Ehdr ehdr_mem;
|
||||
+ GElf_Ehdr *ehdr = gelf_getehdr (scn->elf, &ehdr_mem);
|
||||
+ if (shdr != NULL && (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) &&
|
||||
+ scn->elf->class == ELFCLASS64 &&
|
||||
+ ehdr != NULL && ehdr->e_machine == EM_MIPS && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
|
||||
+ {
|
||||
+ Elf_Data *d = elf_getdata (scn, NULL);
|
||||
+ if (shdr->sh_type == SHT_REL)
|
||||
+ {
|
||||
+ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_REL, 1, EV_CURRENT);
|
||||
+ int nentries = shdr->sh_size / sh_entsize;
|
||||
+ for (int cnt = 0; cnt < nentries; ++cnt)
|
||||
+ {
|
||||
+ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
|
||||
+ Elf64_Rel *value = &((Elf64_Rel *) data_scn->d.d_buf)[cnt];
|
||||
+ Elf64_Xword info = value->r_info;
|
||||
+ value->r_info = (info >> 32
|
||||
+ | ((info << 56) & 0xff00000000000000)
|
||||
+ | ((info << 40) & 0xff000000000000)
|
||||
+ | ((info << 24) & 0xff0000000000)
|
||||
+ | ((info << 8) & 0xff00000000));
|
||||
+ ((Elf64_Rel *) data_scn->d.d_buf)[cnt] = *value;
|
||||
+ }
|
||||
+ }
|
||||
+ else if (shdr->sh_type == SHT_RELA)
|
||||
+ {
|
||||
+ size_t sh_entsize = gelf_fsize (scn->elf, ELF_T_RELA, 1, EV_CURRENT);
|
||||
+ int nentries = shdr->sh_size / sh_entsize;
|
||||
+ for (int cnt = 0; cnt < nentries; cnt++)
|
||||
+ {
|
||||
+ Elf_Data_Scn *data_scn = (Elf_Data_Scn *) d;
|
||||
+ Elf64_Rela *value = &((Elf64_Rela *) data_scn->d.d_buf)[cnt];
|
||||
+ Elf64_Xword info = value->r_info;
|
||||
+ value->r_info = (info >> 32
|
||||
+ | ((info << 56) & 0xff00000000000000)
|
||||
+ | ((info << 40) & 0xff000000000000)
|
||||
+ | ((info << 24) & 0xff0000000000)
|
||||
+ | ((info << 8) & 0xff00000000));
|
||||
+ ((Elf64_Rela *) data_scn->d.d_buf)[cnt] = *value;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
size = write_file (elf, size, change_bo, shnum);
|
||||
+ }
|
||||
}
|
||||
|
||||
out:
|
1079
tools/elfutils/patches/012-backport-mips-support-readelf.patch
Normal file
1079
tools/elfutils/patches/012-backport-mips-support-readelf.patch
Normal file
File diff suppressed because it is too large
Load Diff
157
tools/elfutils/patches/013-backport-mips-support-elflint.patch
Normal file
157
tools/elfutils/patches/013-backport-mips-support-elflint.patch
Normal file
@ -0,0 +1,157 @@
|
||||
The errors were:
|
||||
$ src/elflint --gnu src/nm
|
||||
section [ 2] '.MIPS.options' contains unknown flag(s) 0x8000000
|
||||
section [ 7] '.dynsym': symbol 165 (_DYNAMIC_LINKING): non-local section symbol
|
||||
section [24] '.got' contains invalid processor-specific flag(s) 0x10000000
|
||||
section [25] '.sdata' contains invalid processor-specific flag(s) 0x10000000
|
||||
section [29] '.debug_aranges' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [30] '.debug_info' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [31] '.debug_abbrev' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [32] '.debug_line' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [33] '.debug_frame' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [34] '.debug_str' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [35] '.debug_loc' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [36] '.debug_ranges' has wrong type: expected PROGBITS, is MIPS_DWARF
|
||||
section [38] '.symtab': symbol 785 (_gp): st_value out of bounds
|
||||
section [38] '.symtab': symbol 910 (_fbss): st_value out of bounds
|
||||
section [38] '.symtab': symbol 1051 (_DYNAMIC_LINKING): non-local section symbol
|
||||
|
||||
After fixing:
|
||||
$ src/elflint --gnu src/nm
|
||||
No errors
|
||||
|
||||
Signed-off-by: Ying Huang <ying.huang@oss.cipunited.com>
|
||||
---
|
||||
backends/mips_init.c | 3 +++
|
||||
backends/mips_symbol.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
src/elflint.c | 26 +++++++++++++++++++++-----
|
||||
3 files changed, 61 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/backends/mips_init.c
|
||||
+++ b/backends/mips_init.c
|
||||
@@ -51,10 +51,13 @@ mips_init (Elf *elf __attribute__ ((unus
|
||||
HOOK (eh, section_type_name);
|
||||
HOOK (eh, machine_flag_check);
|
||||
HOOK (eh, machine_flag_name);
|
||||
+ HOOK (eh, machine_section_flag_check);
|
||||
HOOK (eh, segment_type_name);
|
||||
HOOK (eh, dynamic_tag_check);
|
||||
HOOK (eh, dynamic_tag_name);
|
||||
HOOK (eh, check_object_attribute);
|
||||
+ HOOK (eh, check_special_symbol);
|
||||
+ HOOK (eh, check_reloc_target_type);
|
||||
HOOK (eh, set_initial_registers_tid);
|
||||
HOOK (eh, abi_cfi);
|
||||
HOOK (eh, unwind);
|
||||
--- a/backends/mips_symbol.c
|
||||
+++ b/backends/mips_symbol.c
|
||||
@@ -158,6 +158,43 @@ mips_section_type_name (int type,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+bool
|
||||
+mips_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type)
|
||||
+{
|
||||
+ return (sh_type == SHT_MIPS_DWARF);
|
||||
+}
|
||||
+
|
||||
+/* Check whether given symbol's st_value and st_size are OK despite failing
|
||||
+ normal checks. */
|
||||
+bool
|
||||
+mips_check_special_symbol (Elf *elf,
|
||||
+ const GElf_Sym *sym __attribute__ ((unused)),
|
||||
+ const char *name __attribute__ ((unused)),
|
||||
+ const GElf_Shdr *destshdr)
|
||||
+{
|
||||
+ size_t shstrndx;
|
||||
+ if (elf_getshdrstrndx (elf, &shstrndx) != 0)
|
||||
+ return false;
|
||||
+ const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name);
|
||||
+ if (sname == NULL)
|
||||
+ return false;
|
||||
+ return (strcmp (sname, ".got") == 0 || strcmp (sname, ".bss") == 0);
|
||||
+}
|
||||
+
|
||||
+/* Check whether SHF_MASKPROC flags are valid. */
|
||||
+bool
|
||||
+mips_machine_section_flag_check (GElf_Xword sh_flags)
|
||||
+{
|
||||
+ return ((sh_flags &~ (SHF_MIPS_GPREL |
|
||||
+ SHF_MIPS_MERGE |
|
||||
+ SHF_MIPS_ADDR |
|
||||
+ SHF_MIPS_STRINGS |
|
||||
+ SHF_MIPS_NOSTRIP |
|
||||
+ SHF_MIPS_LOCAL |
|
||||
+ SHF_MIPS_NAMES |
|
||||
+ SHF_MIPS_NODUPE)) == 0);
|
||||
+}
|
||||
+
|
||||
/* Check whether machine flags are valid. */
|
||||
bool
|
||||
mips_machine_flag_check (GElf_Word flags)
|
||||
--- a/src/elflint.c
|
||||
+++ b/src/elflint.c
|
||||
@@ -936,7 +936,9 @@ section [%2d] '%s': symbol %zu (%s): non
|
||||
}
|
||||
|
||||
if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
|
||||
- && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
|
||||
+ && GELF_ST_BIND (sym->st_info) != STB_LOCAL
|
||||
+ && ehdr->e_machine != EM_MIPS
|
||||
+ && strcmp (name, "_DYNAMIC_LINKING") != 0)
|
||||
ERROR (_("\
|
||||
section [%2d] '%s': symbol %zu (%s): non-local section symbol\n"),
|
||||
idx, section_name (ebl, idx), cnt, name);
|
||||
@@ -3829,6 +3831,10 @@ cannot get section header for section [%
|
||||
&& ebl_bss_plt_p (ebl))
|
||||
good_type = SHT_NOBITS;
|
||||
|
||||
+ if (ehdr->e_machine == EM_MIPS
|
||||
+ && (strstr(special_sections[s].name, ".debug") != NULL))
|
||||
+ good_type = SHT_MIPS_DWARF;
|
||||
+
|
||||
/* In a debuginfo file, any normal section can be SHT_NOBITS.
|
||||
This is only invalid for DWARF sections and .shstrtab. */
|
||||
if (shdr->sh_type != good_type
|
||||
@@ -3989,12 +3995,21 @@ section [%2zu] '%s': size not multiple o
|
||||
ERROR (_("section [%2zu] '%s'"
|
||||
" contains invalid processor-specific flag(s)"
|
||||
" %#" PRIx64 "\n"),
|
||||
- cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
|
||||
+ cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
|
||||
sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
|
||||
}
|
||||
if (sh_flags & SHF_MASKOS)
|
||||
- if (gnuld)
|
||||
- sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
|
||||
+ {
|
||||
+ if (gnuld)
|
||||
+ sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN;
|
||||
+ if (!ebl_machine_section_flag_check (ebl,
|
||||
+ sh_flags & SHF_MASKOS))
|
||||
+ ERROR (_("section [%2zu] '%s'"
|
||||
+ " contains invalid os-specific flag(s)"
|
||||
+ " %#" PRIx64 "\n"),
|
||||
+ cnt, section_name (ebl, cnt), sh_flags & SHF_MASKOS);
|
||||
+ sh_flags &= ~(GElf_Xword) SHF_MASKOS;
|
||||
+ }
|
||||
if (sh_flags != 0)
|
||||
ERROR (_("section [%2zu] '%s' contains unknown flag(s)"
|
||||
" %#" PRIx64 "\n"),
|
||||
@@ -4060,6 +4075,7 @@ section [%2zu] '%s': merge flag set but
|
||||
switch (shdr->sh_type)
|
||||
{
|
||||
case SHT_PROGBITS:
|
||||
+ case SHT_MIPS_DWARF:
|
||||
break;
|
||||
|
||||
case SHT_NOBITS:
|
||||
@@ -4717,7 +4733,7 @@ program header offset in ELF header and
|
||||
if (shdr != NULL
|
||||
&& ((is_debuginfo && shdr->sh_type == SHT_NOBITS)
|
||||
|| (! is_debuginfo
|
||||
- && (shdr->sh_type == SHT_PROGBITS
|
||||
+ && (is_debug_section_type(shdr->sh_type)
|
||||
|| shdr->sh_type == SHT_X86_64_UNWIND)))
|
||||
&& elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
|
||||
&& ! strcmp (".eh_frame_hdr",
|
@ -23,7 +23,7 @@
|
||||
# Only available since automake 1.12
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
AC_CHECK_TOOL([READELF], [readelf])
|
||||
@@ -635,6 +639,8 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
|
||||
@@ -646,6 +650,8 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
|
||||
CFLAGS="$old_CFLAGS"])
|
||||
AS_IF([test "x$ac_cv_fno_addrsig" = "xyes"], CFLAGS="$CFLAGS -fno-addrsig")
|
||||
|
||||
@ -34,9 +34,9 @@
|
||||
LIBS="$saved_LIBS"
|
||||
--- a/lib/eu-config.h
|
||||
+++ b/lib/eu-config.h
|
||||
@@ -59,14 +59,19 @@
|
||||
# define once(once_control, init_routine) init_routine()
|
||||
#endif /* USE_LOCKS */
|
||||
@@ -31,14 +31,19 @@
|
||||
|
||||
#include "locks.h"
|
||||
|
||||
-#include <libintl.h>
|
||||
+#include <gettext.h>
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
#ifdef __i386__
|
||||
# define internal_function __attribute__ ((regparm (3), stdcall))
|
||||
@@ -77,7 +82,7 @@
|
||||
@@ -49,7 +54,7 @@
|
||||
#define internal_strong_alias(name, aliasname) \
|
||||
extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function;
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
#define attribute_hidden \
|
||||
__attribute__ ((visibility ("hidden")))
|
||||
#else
|
||||
@@ -166,7 +171,7 @@ asm (".section predict_data, \"aw\"; .pr
|
||||
@@ -138,7 +143,7 @@ asm (".section predict_data, \"aw\"; .pr
|
||||
#endif
|
||||
|
||||
/* Avoid PLT entries. */
|
||||
@ -203,7 +203,7 @@
|
||||
+#include <libeu.h>
|
||||
#include <libdw.h>
|
||||
#include <dwarf.h>
|
||||
|
||||
#include "eu-search.h"
|
||||
--- a/config/libdebuginfod.pc.in
|
||||
+++ b/config/libdebuginfod.pc.in
|
||||
@@ -8,5 +8,5 @@ Description: elfutils library to query d
|
||||
@ -235,19 +235,9 @@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
Requires.private: zlib @LIBZSTD@
|
||||
--- a/lib/next_prime.c
|
||||
+++ b/lib/next_prime.c
|
||||
@@ -27,6 +27,7 @@
|
||||
the GNU Lesser General Public License along with this program. If
|
||||
not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
+#include <config.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
--- a/libebl/eblopenbackend.c
|
||||
+++ b/libebl/eblopenbackend.c
|
||||
@@ -200,8 +200,6 @@ static bool default_object_note (const c
|
||||
@@ -202,8 +202,6 @@ static bool default_object_note (const c
|
||||
uint32_t descsz, const char *desc);
|
||||
static bool default_debugscn_p (const char *name);
|
||||
static bool default_copy_reloc_p (int reloc);
|
||||
@ -256,7 +246,7 @@
|
||||
static bool default_check_special_symbol (Elf *elf,
|
||||
const GElf_Sym *sym,
|
||||
const char *name,
|
||||
@@ -253,8 +251,8 @@ fill_defaults (Ebl *result)
|
||||
@@ -255,8 +253,8 @@ fill_defaults (Ebl *result)
|
||||
result->object_note = default_object_note;
|
||||
result->debugscn_p = default_debugscn_p;
|
||||
result->copy_reloc_p = default_copy_reloc_p;
|
||||
@ -267,7 +257,7 @@
|
||||
result->check_special_symbol = default_check_special_symbol;
|
||||
result->data_marker_symbol = default_data_marker_symbol;
|
||||
result->check_st_other_bits = default_check_st_other_bits;
|
||||
@@ -636,8 +634,6 @@ default_copy_reloc_p (int reloc __attrib
|
||||
@@ -638,8 +636,6 @@ default_copy_reloc_p (int reloc __attrib
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -276,25 +266,3 @@
|
||||
|
||||
static bool
|
||||
default_check_special_symbol (Elf *elf __attribute__ ((unused)),
|
||||
--- a/src/srcfiles.cxx
|
||||
+++ b/src/srcfiles.cxx
|
||||
@@ -78,7 +78,9 @@ ARGP_PROGRAM_VERSION_HOOK_DEF = print_ve
|
||||
/* Bug report address. */
|
||||
ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
|
||||
|
||||
+#ifdef HAVE_LIBARCHIVE
|
||||
constexpr size_t BUFFER_SIZE = 8192;
|
||||
+#endif
|
||||
|
||||
/* Definitions of arguments for argp functions. */
|
||||
static const struct argp_option options[] =
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -92,6 +92,7 @@ strings_LDADD = $(libelf) $(libeu) $(arg
|
||||
ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD) $(obstack_LIBS)
|
||||
unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
|
||||
stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) $(demanglelib)
|
||||
+EXTRA_stack_DEPENDENCIES = $(if $(findstring srcfiles,$(bin_PROGRAMS)),$(srcfiles_OBJECTS))
|
||||
elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
|
||||
elfclassify_LDADD = $(libelf) $(libdw) $(libeu) $(argp_LDADD)
|
||||
srcfiles_SOURCES = srcfiles.cxx
|
||||
|
@ -9,7 +9,7 @@
|
||||
AC_CACHE_CHECK([whether gcc supports __attribute__((visibility()))],
|
||||
ac_cv_visibility, [dnl
|
||||
save_CFLAGS="$CFLAGS"
|
||||
@@ -419,7 +421,10 @@ AS_HELP_STRING([--enable-install-elfh],[
|
||||
@@ -423,7 +425,10 @@ AS_HELP_STRING([--enable-install-elfh],[
|
||||
AM_CONDITIONAL(INSTALL_ELFH, test "$install_elfh" = yes)
|
||||
|
||||
AM_CONDITIONAL(BUILD_STATIC, [dnl
|
||||
@ -64,7 +64,7 @@
|
||||
|
||||
include_HEADERS = dwarf.h
|
||||
pkginclude_HEADERS = libdw.h known-dwarf.h
|
||||
@@ -121,11 +123,13 @@ libdw.so: $(srcdir)/libdw.map $(libdw_so
|
||||
@@ -120,11 +122,13 @@ libdw.so: $(srcdir)/libdw.map $(libdw_so
|
||||
@$(textrel_check)
|
||||
$(AM_V_at)ln -fs $@ $@.$(VERSION)
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
|
||||
uninstall: uninstall-am
|
||||
rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
|
||||
@@ -148,6 +152,10 @@ libdw_a_LIBADD += $(addprefix ../backend
|
||||
@@ -147,6 +151,10 @@ libdw_a_LIBADD += $(addprefix ../backend
|
||||
libcpu_objects = $(shell $(AR) t ../libcpu/libcpu.a)
|
||||
libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
|
||||
|
||||
@ -132,7 +132,7 @@
|
||||
|
||||
libdebuginfod_a_SOURCES = debuginfod-client.c
|
||||
libdebuginfod_pic_a_SOURCES = debuginfod-client.c
|
||||
@@ -111,12 +113,16 @@ $(LIBDEBUGINFOD_SONAME): $(srcdir)/libde
|
||||
@@ -111,12 +113,17 @@ $(LIBDEBUGINFOD_SONAME): $(srcdir)/libde
|
||||
libdebuginfod.so: $(LIBDEBUGINFOD_SONAME)
|
||||
ln -fs $< $@
|
||||
|
||||
@ -146,9 +146,10 @@
|
||||
+else
|
||||
+libdebuginfod_a_LIBADD = $(foreach dep,$(wildcard $(libdebuginfod_so_LDLIBS:.so=.a)) $(LIBS:.so=.a),$(if $(findstring a,$(suffix $(dep))),$(addprefix $(dir $(dep)),$(shell cat $(basename $(dep)).manifest)),$(dep)))
|
||||
+endif
|
||||
|
||||
+
|
||||
uninstall: uninstall-am
|
||||
rm -f $(DESTDIR)$(libdir)/libdebuginfod-$(PACKAGE_VERSION).so
|
||||
rm -f $(DESTDIR)$(libdir)/$(LIBDEBUGINFOD_SONAME)
|
||||
--- a/tests/Makefile.am
|
||||
+++ b/tests/Makefile.am
|
||||
@@ -50,7 +50,7 @@ check_PROGRAMS = arextract arsymtest new
|
||||
@ -158,9 +159,9 @@
|
||||
- buildid deleted deleted-lib.so aggregate_size peel_type \
|
||||
+ buildid aggregate_size peel_type \
|
||||
vdsosyms \
|
||||
getsrc_die strptr newdata elfstrtab dwfl-proc-attach \
|
||||
elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr \
|
||||
@@ -180,7 +180,7 @@ TESTS = run-arextract.sh run-arsymtest.s
|
||||
getsrc_die strptr newdata newzdata \
|
||||
elfstrtab dwfl-proc-attach \
|
||||
@@ -181,7 +181,7 @@ TESTS = run-arextract.sh run-arsymtest.s
|
||||
run-readelf-addr.sh run-readelf-str.sh \
|
||||
run-readelf-multi-noline.sh \
|
||||
run-readelf-types.sh \
|
||||
@ -168,10 +169,10 @@
|
||||
+ run-readelf-dwz-multi.sh run-allfcts-multi.sh \
|
||||
run-linkmap-cut.sh run-aggregate-size.sh run-peel-type.sh \
|
||||
vdsosyms run-readelf-A.sh \
|
||||
run-getsrc-die.sh run-strptr.sh newdata elfstrtab dwfl-proc-attach \
|
||||
@@ -284,6 +284,11 @@ funcretval_test__11_SOURCES = funcretval
|
||||
TESTS += run-funcretval++11.sh
|
||||
endif
|
||||
run-getsrc-die.sh run-strptr.sh newdata newzdata \
|
||||
@@ -298,6 +298,11 @@ check_PROGRAMS += funcretval_test_struct
|
||||
funcretval_test_struct_SOURCES = funcretval_test_struct.c
|
||||
TESTS += run-funcretval-struct-native.sh
|
||||
|
||||
+if BUILD_SHARED
|
||||
+check_PROGRAMS += deleted deleted-lib.so
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/libdw/Makefile.am
|
||||
+++ b/libdw/Makefile.am
|
||||
@@ -137,19 +137,19 @@ uninstall: uninstall-am
|
||||
@@ -136,19 +136,19 @@ uninstall: uninstall-am
|
||||
rm -f $(DESTDIR)$(libdir)/libdw.so
|
||||
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
libdw_a_LIBADD += $(addprefix ../libcpu/,$(libcpu_objects))
|
||||
|
||||
if !BUILD_SHARED
|
||||
@@ -161,4 +161,9 @@ noinst_HEADERS = libdwP.h memory-access.
|
||||
@@ -160,5 +160,10 @@ noinst_HEADERS = libdwP.h memory-access.
|
||||
|
||||
EXTRA_DIST = libdw.map
|
||||
|
||||
@ -36,9 +36,10 @@
|
||||
+ echo $^ > $@
|
||||
+
|
||||
+MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) $(EXTRA_libdw_a_DEPENDENCIES) libdw.so libdw.so.$(VERSION)
|
||||
MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h
|
||||
--- a/libdwfl/Makefile.am
|
||||
+++ b/libdwfl/Makefile.am
|
||||
@@ -93,4 +93,10 @@ am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_S
|
||||
@@ -94,4 +94,10 @@ am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_S
|
||||
|
||||
noinst_HEADERS = libdwflP.h
|
||||
|
||||
@ -77,7 +78,7 @@
|
||||
+MOSTLYCLEANFILES = $(am_libebl_pic_a_OBJECTS) $(EXTRA_libebl_a_DEPENDENCIES)
|
||||
--- a/backends/Makefile.am
|
||||
+++ b/backends/Makefile.am
|
||||
@@ -119,4 +119,9 @@ am_libebl_backends_pic_a_OBJECTS = $(lib
|
||||
@@ -122,4 +122,9 @@ am_libebl_backends_pic_a_OBJECTS = $(lib
|
||||
noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c
|
||||
EXTRA_DIST = $(modules:=_reloc.def)
|
||||
|
||||
@ -118,9 +119,9 @@
|
||||
CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so libelf.so.$(VERSION)
|
||||
--- a/lib/Makefile.am
|
||||
+++ b/lib/Makefile.am
|
||||
@@ -41,3 +41,10 @@ noinst_HEADERS = fixedsizehash.h libeu.h
|
||||
eu-config.h color.h printversion.h bpf.h \
|
||||
atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h
|
||||
@@ -42,3 +42,10 @@ noinst_HEADERS = fixedsizehash.h libeu.h
|
||||
atomics.h stdatomic-fbsd.h dynamicsizehash_concurrent.h \
|
||||
eu-search.h locks.h
|
||||
EXTRA_DIST = dynamicsizehash.c dynamicsizehash_concurrent.c
|
||||
+
|
||||
+EXTRA_libeu_a_DEPENDENCIES = libeu.manifest
|
||||
|
@ -2,11 +2,11 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gnulib
|
||||
PKG_CPE_ID:=cpe:/a:gnu:$(PKG_NAME)
|
||||
PKG_VERSION:=c99c8d491850dc3a6e0b8604a2729d8bc5c0eff1# # stable-202401
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://git.savannah.gnu.org/cgit/$(PKG_NAME).git/snapshot
|
||||
PKG_HASH:=8e6f4a907d9677b55fd452e1340a3e030a6f530b138d420c11975da33f086b1e
|
||||
PKG_SOURCE_URL=git://git.git.savannah.gnu.org/$(PKG_NAME).git
|
||||
PKG_SOURCE_DATE:=2025-07-01
|
||||
PKG_SOURCE_VERSION:=a3151d456d6919c9066b54dc6f680452168165cf# # stable-202501
|
||||
PKG_MIRROR_HASH:=b695d96e915ecd6c4551436f417cb2c0879aef4ef6318721c8d5cc86cb44ba9d
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
@ -14,14 +14,14 @@ define Host/Configure
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(call Host/Uninstall)
|
||||
$(INSTALL_DIR) $(1)/share/aclocal
|
||||
$(INSTALL_DATA) $(HOST_BUILD_DIR)/m4/*.m4 $(1)/share/aclocal/
|
||||
$(INSTALL_DIR) $(1)/share/gnulib
|
||||
$(CP) $(HOST_BUILD_DIR)/* $(1)/share/gnulib/
|
||||
$(CP) $(HOST_BUILD_DIR)/ $(1)/share/gnulib/
|
||||
ln -sf ../share/gnulib/gnulib-tool $(STAGING_DIR_HOST)/bin/gnulib-tool
|
||||
endef
|
||||
|
||||
define Host/Clean
|
||||
define Host/Uninstall
|
||||
rm -rf $(STAGING_DIR_HOST)/bin/gnulib-tool $(STAGING_DIR_HOST)/share/gnulib
|
||||
endef
|
||||
|
||||
|
@ -43,7 +43,7 @@
|
||||
if [ ! "$inst_ver" ]; then
|
||||
warn_ "Error: '$app' not found"
|
||||
ret=1
|
||||
@@ -1157,7 +1157,7 @@ autogen()
|
||||
@@ -1205,7 +1205,7 @@ autogen()
|
||||
# two just-pre-run programs.
|
||||
|
||||
# Import from gettext.
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/gnulib-tool
|
||||
+++ b/gnulib-tool
|
||||
@@ -346,6 +346,34 @@ Options for --import, --add/remove-impor
|
||||
--- a/gnulib-tool.sh
|
||||
+++ b/gnulib-tool.sh
|
||||
@@ -344,6 +344,34 @@ Options for --import, --add/remove-impor
|
||||
Report bugs to <bug-gnulib@gnu.org>."
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
# func_version
|
||||
# outputs to stdout the --version message.
|
||||
func_version ()
|
||||
@@ -1620,6 +1648,9 @@ func_determine_path_separator
|
||||
@@ -1666,6 +1694,9 @@ func_determine_path_separator
|
||||
fi
|
||||
case "$autoconf_minversion" in
|
||||
1.* | 2.[0-5]* | 2.6[0-3]*)
|
||||
|
47
tools/gnulib/patches/020-python-version.patch
Normal file
47
tools/gnulib/patches/020-python-version.patch
Normal file
@ -0,0 +1,47 @@
|
||||
--- a/pygnulib/functions.py
|
||||
+++ b/pygnulib/functions.py
|
||||
@@ -16,6 +16,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os.path
|
||||
+import re
|
||||
+import subprocess as sp
|
||||
from .constants import substart
|
||||
from .GLConfig import GLConfig
|
||||
|
||||
@@ -50,3 +52,15 @@ def rewrite_file_name(file_name: str, co
|
||||
else: # file is not a special file
|
||||
result = file_name
|
||||
return os.path.normpath(result)
|
||||
+
|
||||
+def get_version(app: str) -> str:
|
||||
+ result = sp.run([app, '--version'], capture_output=True, text=True)
|
||||
+ version = re.sub(r".*[v ]([0-9])", r"\1", result.stdout)
|
||||
+ version_lines = [line for line in version.splitlines() if re.search(r"^[0-9]", line)]
|
||||
+ version = '\n'.join(version_lines) + "\n"
|
||||
+ version = re.sub(r"[^.a-z0-9-\n].*", r"", version)
|
||||
+ version = re.sub(r"^([0-9]*)[a-z-].*", r"\1", version, 1)
|
||||
+ version = re.sub(r"\.0*([1-9])", r".\1", version)
|
||||
+ version_lines = [line for line in version.splitlines() if line.strip()]
|
||||
+ version = ''.join(version_lines[0]) + "\n"
|
||||
+ return version.strip()
|
||||
--- a/pygnulib/GLImport.py
|
||||
+++ b/pygnulib/GLImport.py
|
||||
@@ -40,6 +40,7 @@ from .constants import (
|
||||
rmtree,
|
||||
)
|
||||
from .functions import rewrite_file_name
|
||||
+from .functions import get_version
|
||||
from .GLError import GLError
|
||||
from .GLConfig import GLConfig
|
||||
from .GLModuleSystem import GLModuleTable
|
||||
@@ -125,7 +126,8 @@ class GLImport:
|
||||
for version in versions })
|
||||
self.config.setAutoconfVersion(version)
|
||||
if version < 2.64:
|
||||
- raise GLError(4, version)
|
||||
+ # If the version of autoconf in use is high enough, do not error.
|
||||
+ if float(get_version('autoconf')) < 2.64: raise GLError(4, version)
|
||||
|
||||
# Get other cached variables.
|
||||
path = joinpath(self.config['m4base'], 'gnulib-cache.m4')
|
@ -107,7 +107,7 @@
|
||||
+#endif /* defined(_LIBC) || GNULIB_defined_tdestroy */
|
||||
--- a/m4/search_h.m4
|
||||
+++ b/m4/search_h.m4
|
||||
@@ -39,7 +39,7 @@ AC_DEFUN_ONCE([gl_SEARCH_H],
|
||||
@@ -41,7 +41,7 @@ AC_DEFUN_ONCE([gl_SEARCH_H],
|
||||
dnl Check for declarations of anything we want to poison if the
|
||||
dnl corresponding gnulib module is not in use.
|
||||
gl_WARN_ON_USE_PREPARE([[#include <search.h>
|
||||
@ -116,7 +116,7 @@
|
||||
|
||||
AC_REQUIRE([AC_C_RESTRICT])
|
||||
])
|
||||
@@ -75,8 +75,10 @@ AC_DEFUN([gl_SEARCH_H_DEFAULTS],
|
||||
@@ -77,8 +77,10 @@ AC_DEFUN([gl_SEARCH_H_DEFAULTS],
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LFIND], [1])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_LSEARCH], [1])
|
||||
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||
@ -133,7 +133,7 @@
|
||||
])
|
||||
--- a/m4/tsearch.m4
|
||||
+++ b/m4/tsearch.m4
|
||||
@@ -9,6 +9,7 @@ AC_DEFUN([gl_FUNC_TSEARCH],
|
||||
@@ -11,6 +11,7 @@ AC_DEFUN([gl_FUNC_TSEARCH],
|
||||
AC_REQUIRE([gl_SEARCH_H_DEFAULTS])
|
||||
gl_CHECK_FUNCS_ANDROID([tsearch], [[#include <search.h>]])
|
||||
gl_CHECK_FUNCS_ANDROID([twalk], [[#include <search.h>]])
|
||||
@ -141,7 +141,7 @@
|
||||
if test $ac_cv_func_tsearch = yes; then
|
||||
dnl On OpenBSD 4.0, the return value of tdelete() is incorrect.
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
@@ -50,6 +51,7 @@ main ()
|
||||
@@ -52,6 +53,7 @@ main ()
|
||||
*no)
|
||||
REPLACE_TSEARCH=1
|
||||
REPLACE_TWALK=1
|
||||
@ -149,7 +149,7 @@
|
||||
;;
|
||||
esac
|
||||
else
|
||||
@@ -64,6 +66,12 @@ main ()
|
||||
@@ -66,6 +68,12 @@ main ()
|
||||
future*) REPLACE_TWALK=1 ;;
|
||||
esac
|
||||
fi
|
||||
@ -162,8 +162,8 @@
|
||||
])
|
||||
|
||||
# Prerequisites of lib/tsearch.c.
|
||||
--- a/modules/search
|
||||
+++ b/modules/search
|
||||
--- a/modules/search-h
|
||||
+++ b/modules/search-h
|
||||
@@ -37,8 +37,10 @@ search.h: search.in.h $(top_builddir)/co
|
||||
-e 's/@''GNULIB_MDA_LSEARCH''@/$(GNULIB_MDA_LSEARCH)/g' \
|
||||
-e 's|@''HAVE_TSEARCH''@|$(HAVE_TSEARCH)|g' \
|
||||
@ -177,7 +177,7 @@
|
||||
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
|
||||
--- a/modules/tsearch
|
||||
+++ b/modules/tsearch
|
||||
@@ -11,7 +11,12 @@ search
|
||||
@@ -11,7 +11,12 @@ search-h
|
||||
configure.ac:
|
||||
gl_FUNC_TSEARCH
|
||||
gl_CONDITIONAL([GL_COND_OBJ_TSEARCH],
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/lib/ialloc.h
|
||||
+++ b/lib/ialloc.h
|
||||
@@ -106,6 +106,8 @@ icalloc (idx_t n, idx_t s)
|
||||
@@ -91,6 +91,8 @@ icalloc (idx_t n, idx_t s)
|
||||
return calloc (n, s);
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
/* ireallocarray (ptr, num, size) is like reallocarray (ptr, num, size).
|
||||
It returns a non-NULL pointer to num * size bytes of memory.
|
||||
Upon failure, it returns NULL with errno set. */
|
||||
@@ -131,6 +133,8 @@ ireallocarray (void *p, idx_t n, idx_t s
|
||||
return _gl_alloc_nomem ();
|
||||
@@ -102,6 +104,8 @@ ireallocarray (void *p, idx_t n, idx_t s
|
||||
: _gl_alloc_nomem ());
|
||||
}
|
||||
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
@ -21,7 +21,7 @@
|
||||
--- a/lib/xmalloc.c
|
||||
+++ b/lib/xmalloc.c
|
||||
@@ -51,12 +51,16 @@ ximalloc (idx_t s)
|
||||
return nonnull (imalloc (s));
|
||||
return check_nonnull (imalloc (s));
|
||||
}
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
@ -38,7 +38,7 @@
|
||||
with error checking. */
|
||||
|
||||
@@ -75,6 +79,8 @@ xirealloc (void *p, idx_t s)
|
||||
return nonnull (irealloc (p, s));
|
||||
return check_nonnull (irealloc (p, s));
|
||||
}
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
@ -57,7 +57,24 @@
|
||||
new size. The new array will contain at least N_INCR_MIN more
|
||||
--- a/lib/xalloc.h
|
||||
+++ b/lib/xalloc.h
|
||||
@@ -129,6 +129,7 @@ char *xstrdup (char const *str)
|
||||
@@ -81,10 +81,16 @@ void *xrealloc (void *p, size_t s)
|
||||
_GL_ATTRIBUTE_ALLOC_SIZE ((2));
|
||||
void *xirealloc (void *p, idx_t s)
|
||||
_GL_ATTRIBUTE_ALLOC_SIZE ((2)) _GL_ATTRIBUTE_RETURNS_NONNULL;
|
||||
+
|
||||
+# if GNULIB_REALLOCARRAY
|
||||
+
|
||||
void *xreallocarray (void *p, size_t n, size_t s)
|
||||
_GL_ATTRIBUTE_ALLOC_SIZE ((2, 3));
|
||||
void *xireallocarray (void *p, idx_t n, idx_t s)
|
||||
_GL_ATTRIBUTE_ALLOC_SIZE ((2, 3)) _GL_ATTRIBUTE_RETURNS_NONNULL;
|
||||
+
|
||||
+# endif /* GNULIB_REALLOCARRAY */
|
||||
+
|
||||
void *x2realloc (void *p, size_t *ps) /* superseded by xpalloc */
|
||||
_GL_ATTRIBUTE_RETURNS_NONNULL;
|
||||
void *x2nrealloc (void *p, size_t *pn, size_t s) /* superseded by xpalloc */
|
||||
@@ -129,6 +135,7 @@ char *xstrdup (char const *str)
|
||||
# define XCALLOC(n, t) \
|
||||
((t *) (sizeof (t) == 1 ? xzalloc (n) : xcalloc (n, sizeof (t))))
|
||||
|
||||
@ -65,7 +82,7 @@
|
||||
|
||||
/* Allocate an array of N objects, each with S bytes of memory,
|
||||
dynamically, with error checking. S must be nonzero. */
|
||||
@@ -156,6 +157,8 @@ char *xcharalloc (size_t n)
|
||||
@@ -156,6 +163,8 @@ char *xcharalloc (size_t n)
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC_FREE
|
||||
_GL_ATTRIBUTE_ALLOC_SIZE ((1)) _GL_ATTRIBUTE_RETURNS_NONNULL;
|
||||
|
||||
@ -76,26 +93,15 @@
|
||||
|
||||
--- a/lib/safe-alloc.h
|
||||
+++ b/lib/safe-alloc.h
|
||||
@@ -36,6 +36,8 @@ _GL_INLINE_HEADER_BEGIN
|
||||
# define SAFE_ALLOC_INLINE _GL_INLINE
|
||||
@@ -37,7 +37,6 @@ _GL_INLINE_HEADER_BEGIN
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
+
|
||||
/* Don't call these directly - use the macros below. */
|
||||
SAFE_ALLOC_INLINE void *
|
||||
safe_alloc_realloc_n (void *ptr, size_t count, size_t size)
|
||||
@@ -51,6 +53,9 @@ safe_alloc_realloc_n (void *ptr, size_t
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
+
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
+
|
||||
-
|
||||
/* Don't call this directly - use the macros below. */
|
||||
_GL_ATTRIBUTE_NODISCARD SAFE_ALLOC_INLINE int
|
||||
safe_alloc_check (void *ptr)
|
||||
{
|
||||
@@ -84,6 +89,8 @@ safe_alloc_check (void *ptr)
|
||||
@@ -72,6 +71,8 @@ safe_alloc_check (void *ptr)
|
||||
#define ALLOC_N(ptr, count) \
|
||||
safe_alloc_check ((ptr) = calloc (count, sizeof *(ptr)))
|
||||
|
||||
@ -104,12 +110,85 @@
|
||||
/**
|
||||
* ALLOC_N_UNINITIALIZED:
|
||||
* @ptr: pointer to allocated memory
|
||||
@@ -112,6 +119,8 @@ safe_alloc_check (void *ptr)
|
||||
@@ -100,6 +101,8 @@ safe_alloc_check (void *ptr)
|
||||
#define REALLOC_N(ptr, count) \
|
||||
safe_alloc_check ((ptr) = safe_alloc_realloc_n (ptr, count, sizeof *(ptr)))
|
||||
safe_alloc_check ((ptr) = reallocarray (ptr, count, sizeof *(ptr)))
|
||||
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
+
|
||||
/**
|
||||
* FREE:
|
||||
* @ptr: pointer holding address to be freed
|
||||
--- a/lib/dfa.c
|
||||
+++ b/lib/dfa.c
|
||||
@@ -1620,6 +1620,8 @@ lex (struct dfa *dfa)
|
||||
}
|
||||
}
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
+
|
||||
static void
|
||||
addtok_mb (struct dfa *dfa, token t, char mbprop)
|
||||
{
|
||||
@@ -1674,6 +1676,8 @@ addtok_mb (struct dfa *dfa, token t, cha
|
||||
}
|
||||
}
|
||||
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
+
|
||||
static void addtok_wc (struct dfa *dfa, wint_t wc);
|
||||
|
||||
/* Add the given token to the parse tree, maintaining the depth count and
|
||||
@@ -2934,6 +2938,8 @@ dfaanalyze (struct dfa *d, bool searchfl
|
||||
free (tmp.elems);
|
||||
}
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
+
|
||||
/* Make sure D's state arrays are large enough to hold NEW_STATE. */
|
||||
static void
|
||||
realloc_trans_if_necessary (struct dfa *d)
|
||||
@@ -2969,6 +2975,8 @@ realloc_trans_if_necessary (struct dfa *
|
||||
}
|
||||
}
|
||||
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
+
|
||||
/*
|
||||
Calculate the transition table for a new state derived from state s
|
||||
for a compiled dfa d after input character uc, and return the new
|
||||
@@ -4010,6 +4018,8 @@ freelist (char **cpp)
|
||||
free (*cpp++);
|
||||
}
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
+
|
||||
static char **
|
||||
enlistnew (char **cpp, char *new)
|
||||
{
|
||||
@@ -4046,6 +4056,8 @@ enlist (char **cpp, char const *str, idx
|
||||
return enlistnew (cpp, ximemdup0 (str, len));
|
||||
}
|
||||
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
+
|
||||
/* Given pointers to two strings, return a pointer to an allocated
|
||||
list of their distinct common substrings. */
|
||||
static char **
|
||||
--- a/lib/readtokens.c
|
||||
+++ b/lib/readtokens.c
|
||||
@@ -128,6 +128,8 @@ readtoken (FILE *stream,
|
||||
return i;
|
||||
}
|
||||
|
||||
+#if GNULIB_REALLOCARRAY
|
||||
+
|
||||
/* Build a NULL-terminated array of pointers to tokens
|
||||
read from STREAM. Return the number of tokens read.
|
||||
All storage is obtained through calls to xmalloc-like functions.
|
||||
@@ -190,3 +192,5 @@ readtokens (FILE *stream,
|
||||
free (lengths);
|
||||
return n_tokens;
|
||||
}
|
||||
+
|
||||
+#endif /* GNULIB_REALLOCARRAY */
|
||||
|
@ -20,8 +20,8 @@
|
||||
{
|
||||
--- a/lib/stdlib.in.h
|
||||
+++ b/lib/stdlib.in.h
|
||||
@@ -1447,10 +1447,16 @@ _GL_FUNCDECL_RPL (reallocarray, void *,
|
||||
(void *ptr, size_t nmemb, size_t size));
|
||||
@@ -1549,11 +1549,17 @@ _GL_FUNCDECL_RPL (reallocarray, void *,
|
||||
_GL_ATTRIBUTE_NODISCARD);
|
||||
_GL_CXXALIAS_RPL (reallocarray, void *,
|
||||
(void *ptr, size_t nmemb, size_t size));
|
||||
+# if !GNULIB_defined_rpl_reallocarray
|
||||
@ -30,7 +30,8 @@
|
||||
# else
|
||||
# if ! @HAVE_REALLOCARRAY@
|
||||
_GL_FUNCDECL_SYS (reallocarray, void *,
|
||||
(void *ptr, size_t nmemb, size_t size));
|
||||
(void *ptr, size_t nmemb, size_t size),
|
||||
_GL_ATTRIBUTE_NODISCARD);
|
||||
+# if !GNULIB_defined_reallocarray
|
||||
+# define GNULIB_defined_reallocarray 1
|
||||
+# endif
|
||||
@ -49,7 +50,7 @@
|
||||
reallocarray (void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
@@ -36,3 +38,5 @@ reallocarray (void *ptr, size_t nmemb, s
|
||||
/* Rely on the semantics of GNU realloc. */
|
||||
/* Call realloc, setting errno to ENOMEM on failure. */
|
||||
return realloc (ptr, nbytes);
|
||||
}
|
||||
+
|
||||
|
@ -69,7 +69,7 @@
|
||||
+AC_DEFUN([gl_PREREQ_POSIX_FALLOCATE], [:])
|
||||
--- a/m4/fcntl_h.m4
|
||||
+++ b/m4/fcntl_h.m4
|
||||
@@ -23,7 +23,7 @@ AC_DEFUN_ONCE([gl_FCNTL_H],
|
||||
@@ -26,7 +26,7 @@ AC_DEFUN_ONCE([gl_FCNTL_H],
|
||||
dnl corresponding gnulib module is not in use, if it is not common
|
||||
dnl enough to be declared everywhere.
|
||||
gl_WARN_ON_USE_PREPARE([[#include <fcntl.h>
|
||||
@ -78,7 +78,7 @@
|
||||
])
|
||||
|
||||
# gl_FCNTL_MODULE_INDICATOR([modulename])
|
||||
@@ -50,6 +50,7 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
|
||||
@@ -53,6 +53,7 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_NONBLOCKING])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPEN])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OPENAT])
|
||||
@ -86,7 +86,7 @@
|
||||
dnl Support Microsoft deprecated alias function names by default.
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_CREAT], [1])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_OPEN], [1])
|
||||
@@ -61,10 +62,12 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
|
||||
@@ -64,10 +65,12 @@ AC_DEFUN([gl_FCNTL_H_REQUIRE_DEFAULTS],
|
||||
AC_DEFUN([gl_FCNTL_H_DEFAULTS],
|
||||
[
|
||||
dnl Assume proper GNU behavior unless another module says otherwise.
|
||||
@ -127,7 +127,7 @@
|
||||
-e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
|
||||
--- a/lib/fcntl.in.h
|
||||
+++ b/lib/fcntl.in.h
|
||||
@@ -238,6 +238,33 @@ _GL_WARN_ON_USE (openat, "openat is not
|
||||
@@ -241,6 +241,33 @@ _GL_WARN_ON_USE (openat, "openat is not
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -316,7 +316,7 @@
|
||||
+}
|
||||
--- a/MODULES.html.sh
|
||||
+++ b/MODULES.html.sh
|
||||
@@ -2552,6 +2552,7 @@ func_all_modules ()
|
||||
@@ -2555,6 +2555,7 @@ func_all_modules ()
|
||||
func_module execve
|
||||
func_module execvp
|
||||
func_module execvpe
|
||||
|
494
tools/gnulib/patches/640-mem-hash-map.patch
Normal file
494
tools/gnulib/patches/640-mem-hash-map.patch
Normal file
@ -0,0 +1,494 @@
|
||||
From 5a842672e79a7a5f6be837c483be4f9901a4ecc0 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 30 Apr 2025 03:19:10 +0200
|
||||
Subject: [PATCH] New module mem-hash-map.
|
||||
|
||||
* lib/mem-hash-map.h: New file, from GNU gettext.
|
||||
* lib/mem-hash-map.c: New file, from GNU gettext.
|
||||
* modules/mem-hash-map: New file, from GNU gettext.
|
||||
---
|
||||
ChangeLog | 7 +
|
||||
lib/mem-hash-map.c | 352 +++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/mem-hash-map.h | 90 +++++++++++
|
||||
modules/mem-hash-map | 25 +++
|
||||
4 files changed, 474 insertions(+)
|
||||
create mode 100644 lib/mem-hash-map.c
|
||||
create mode 100644 lib/mem-hash-map.h
|
||||
create mode 100644 modules/mem-hash-map
|
||||
|
||||
--- /dev/null
|
||||
+++ b/lib/mem-hash-map.c
|
||||
@@ -0,0 +1,352 @@
|
||||
+/* Simple hash table (no removals) where the keys are memory blocks.
|
||||
+ Copyright (C) 1994-2025 Free Software Foundation, Inc.
|
||||
+ Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, October 1994.
|
||||
+
|
||||
+ 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 program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include "mem-hash-map.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <stdio.h>
|
||||
+#include <limits.h>
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+#include "next-prime.h"
|
||||
+
|
||||
+/* Since this simple implementation of hash tables allows only insertion, no
|
||||
+ removal of entries, the right data structure for the memory holding all keys
|
||||
+ is an obstack. */
|
||||
+#include "obstack.h"
|
||||
+
|
||||
+/* Use checked memory allocation. */
|
||||
+#include "xalloc.h"
|
||||
+
|
||||
+#define obstack_chunk_alloc xmalloc
|
||||
+#define obstack_chunk_free free
|
||||
+
|
||||
+
|
||||
+typedef struct hash_entry
|
||||
+{
|
||||
+ size_t used; /* Hash code of the key, or 0 for an unused entry. */
|
||||
+ const void *key; /* Key. */
|
||||
+ size_t keylen;
|
||||
+ void *data; /* Value. */
|
||||
+ struct hash_entry *next;
|
||||
+}
|
||||
+hash_entry;
|
||||
+
|
||||
+
|
||||
+/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available
|
||||
+ entries.
|
||||
+ Return 0 always. */
|
||||
+int
|
||||
+hash_init (hash_table *htab, size_t init_size)
|
||||
+{
|
||||
+ /* We need the size to be a prime. */
|
||||
+ init_size = next_prime (init_size);
|
||||
+
|
||||
+ /* Initialize the data structure. */
|
||||
+ htab->size = init_size;
|
||||
+ htab->filled = 0;
|
||||
+ htab->first = NULL;
|
||||
+ htab->table = XCALLOC (init_size + 1, hash_entry);
|
||||
+
|
||||
+ obstack_init (&htab->mem_pool);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Delete a hash table's contents.
|
||||
+ Return 0 always. */
|
||||
+int
|
||||
+hash_destroy (hash_table *htab)
|
||||
+{
|
||||
+ free (htab->table);
|
||||
+ obstack_free (&htab->mem_pool, NULL);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Compute a hash code for a key consisting of KEYLEN bytes starting at KEY
|
||||
+ in memory. */
|
||||
+static size_t
|
||||
+compute_hashval (const void *key, size_t keylen)
|
||||
+{
|
||||
+ size_t cnt;
|
||||
+ size_t hval;
|
||||
+
|
||||
+ /* Compute the hash value for the given string. The algorithm
|
||||
+ is taken from [Aho,Sethi,Ullman], fixed according to
|
||||
+ https://haible.de/bruno/hashfunc.html. */
|
||||
+ cnt = 0;
|
||||
+ hval = keylen;
|
||||
+ while (cnt < keylen)
|
||||
+ {
|
||||
+ hval = (hval << 9) | (hval >> (sizeof (size_t) * CHAR_BIT - 9));
|
||||
+ hval += (size_t) *(((const char *) key) + cnt++);
|
||||
+ }
|
||||
+ return hval != 0 ? hval : ~((size_t) 0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* References:
|
||||
+ [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986
|
||||
+ [Knuth] The Art of Computer Programming, part3 (6.4) */
|
||||
+
|
||||
+/* Look up a given key in the hash table.
|
||||
+ Return the index of the entry, if present, or otherwise the index a free
|
||||
+ entry where it could be inserted. */
|
||||
+static size_t
|
||||
+lookup (const hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ size_t hval)
|
||||
+{
|
||||
+ size_t hash;
|
||||
+ size_t idx;
|
||||
+ hash_entry *table = htab->table;
|
||||
+
|
||||
+ /* First hash function: simply take the modul but prevent zero. */
|
||||
+ hash = 1 + hval % htab->size;
|
||||
+
|
||||
+ idx = hash;
|
||||
+
|
||||
+ if (table[idx].used)
|
||||
+ {
|
||||
+ if (table[idx].used == hval && table[idx].keylen == keylen
|
||||
+ && memcmp (table[idx].key, key, keylen) == 0)
|
||||
+ return idx;
|
||||
+
|
||||
+ /* Second hash function as suggested in [Knuth]. */
|
||||
+ hash = 1 + hval % (htab->size - 2);
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ if (idx <= hash)
|
||||
+ idx = htab->size + idx - hash;
|
||||
+ else
|
||||
+ idx -= hash;
|
||||
+
|
||||
+ /* If entry is found use it. */
|
||||
+ if (table[idx].used == hval && table[idx].keylen == keylen
|
||||
+ && memcmp (table[idx].key, key, keylen) == 0)
|
||||
+ return idx;
|
||||
+ }
|
||||
+ while (table[idx].used);
|
||||
+ }
|
||||
+ return idx;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Look up the value of a key in the given table.
|
||||
+ If found, return 0 and set *RESULT to it. Otherwise return -1. */
|
||||
+int
|
||||
+hash_find_entry (const hash_table *htab, const void *key, size_t keylen,
|
||||
+ void **result)
|
||||
+{
|
||||
+ hash_entry *table = htab->table;
|
||||
+ size_t idx = lookup (htab, key, keylen, compute_hashval (key, keylen));
|
||||
+
|
||||
+ if (table[idx].used == 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ *result = table[idx].data;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table at index IDX.
|
||||
+ HVAL is the key's hash code. IDX depends on it. The table entry at index
|
||||
+ IDX is known to be unused. */
|
||||
+static void
|
||||
+insert_entry_2 (hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ size_t hval, size_t idx, void *data)
|
||||
+{
|
||||
+ hash_entry *table = htab->table;
|
||||
+
|
||||
+ table[idx].used = hval;
|
||||
+ table[idx].key = key;
|
||||
+ table[idx].keylen = keylen;
|
||||
+ table[idx].data = data;
|
||||
+
|
||||
+ /* List the new value in the list. */
|
||||
+ if (htab->first == NULL)
|
||||
+ {
|
||||
+ table[idx].next = &table[idx];
|
||||
+ htab->first = &table[idx];
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ table[idx].next = htab->first->next;
|
||||
+ htab->first->next = &table[idx];
|
||||
+ htab->first = &table[idx];
|
||||
+ }
|
||||
+
|
||||
+ ++htab->filled;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Grow the hash table. */
|
||||
+static void
|
||||
+resize (hash_table *htab)
|
||||
+{
|
||||
+ size_t old_size = htab->size;
|
||||
+ hash_entry *table = htab->table;
|
||||
+ size_t idx;
|
||||
+
|
||||
+ htab->size = next_prime (htab->size * 2);
|
||||
+ htab->filled = 0;
|
||||
+ htab->first = NULL;
|
||||
+ htab->table = XCALLOC (1 + htab->size, hash_entry);
|
||||
+
|
||||
+ for (idx = 1; idx <= old_size; ++idx)
|
||||
+ if (table[idx].used)
|
||||
+ insert_entry_2 (htab, table[idx].key, table[idx].keylen,
|
||||
+ table[idx].used,
|
||||
+ lookup (htab, table[idx].key, table[idx].keylen,
|
||||
+ table[idx].used),
|
||||
+ table[idx].data);
|
||||
+
|
||||
+ free (table);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
|
||||
+ Return non-NULL (more precisely, the address of the KEY inside the table's
|
||||
+ memory pool) if successful, or NULL if there is already an entry with the
|
||||
+ given key. */
|
||||
+const void *
|
||||
+hash_insert_entry (hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ void *data)
|
||||
+{
|
||||
+ size_t hval = compute_hashval (key, keylen);
|
||||
+ hash_entry *table = htab->table;
|
||||
+ size_t idx = lookup (htab, key, keylen, hval);
|
||||
+
|
||||
+ if (table[idx].used)
|
||||
+ /* We don't want to overwrite the old value. */
|
||||
+ return NULL;
|
||||
+ else
|
||||
+ {
|
||||
+ /* An empty bucket has been found. */
|
||||
+ void *keycopy = obstack_copy (&htab->mem_pool, key, keylen);
|
||||
+ insert_entry_2 (htab, keycopy, keylen, hval, idx, data);
|
||||
+ if (100 * htab->filled > 75 * htab->size)
|
||||
+ /* Table is filled more than 75%. Resize the table. */
|
||||
+ resize (htab);
|
||||
+ return keycopy;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
|
||||
+ Return 0. */
|
||||
+int
|
||||
+hash_set_value (hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ void *data)
|
||||
+{
|
||||
+ size_t hval = compute_hashval (key, keylen);
|
||||
+ hash_entry *table = htab->table;
|
||||
+ size_t idx = lookup (htab, key, keylen, hval);
|
||||
+
|
||||
+ if (table[idx].used)
|
||||
+ {
|
||||
+ /* Overwrite the old value. */
|
||||
+ table[idx].data = data;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* An empty bucket has been found. */
|
||||
+ void *keycopy = obstack_copy (&htab->mem_pool, key, keylen);
|
||||
+ insert_entry_2 (htab, keycopy, keylen, hval, idx, data);
|
||||
+ if (100 * htab->filled > 75 * htab->size)
|
||||
+ /* Table is filled more than 75%. Resize the table. */
|
||||
+ resize (htab);
|
||||
+ return 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Steps *PTR forward to the next used entry in the given hash table. *PTR
|
||||
+ should be initially set to NULL. Store information about the next entry
|
||||
+ in *KEY, *KEYLEN, *DATA.
|
||||
+ Return 0 normally, -1 when the whole hash table has been traversed. */
|
||||
+int
|
||||
+hash_iterate (hash_table *htab, void **ptr, const void **key, size_t *keylen,
|
||||
+ void **data)
|
||||
+{
|
||||
+ hash_entry *curr;
|
||||
+
|
||||
+ if (*ptr == NULL)
|
||||
+ {
|
||||
+ if (htab->first == NULL)
|
||||
+ return -1;
|
||||
+ curr = htab->first;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (*ptr == htab->first)
|
||||
+ return -1;
|
||||
+ curr = (hash_entry *) *ptr;
|
||||
+ }
|
||||
+ curr = curr->next;
|
||||
+ *ptr = (void *) curr;
|
||||
+
|
||||
+ *key = curr->key;
|
||||
+ *keylen = curr->keylen;
|
||||
+ *data = curr->data;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* Steps *PTR forward to the next used entry in the given hash table. *PTR
|
||||
+ should be initially set to NULL. Store information about the next entry
|
||||
+ in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the
|
||||
+ value; modifying **DATAP will modify the value of the entry.
|
||||
+ Return 0 normally, -1 when the whole hash table has been traversed. */
|
||||
+int
|
||||
+hash_iterate_modify (hash_table *htab, void **ptr,
|
||||
+ const void **key, size_t *keylen,
|
||||
+ void ***datap)
|
||||
+{
|
||||
+ hash_entry *curr;
|
||||
+
|
||||
+ if (*ptr == NULL)
|
||||
+ {
|
||||
+ if (htab->first == NULL)
|
||||
+ return -1;
|
||||
+ curr = htab->first;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (*ptr == htab->first)
|
||||
+ return -1;
|
||||
+ curr = (hash_entry *) *ptr;
|
||||
+ }
|
||||
+ curr = curr->next;
|
||||
+ *ptr = (void *) curr;
|
||||
+
|
||||
+ *key = curr->key;
|
||||
+ *keylen = curr->keylen;
|
||||
+ *datap = &curr->data;
|
||||
+ return 0;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/lib/mem-hash-map.h
|
||||
@@ -0,0 +1,90 @@
|
||||
+/* Simple hash table (no removals) where the keys are memory blocks.
|
||||
+ Copyright (C) 1995-2025 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 program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _GL_MEM_HASH_MAP_H
|
||||
+#define _GL_MEM_HASH_MAP_H
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+#include "obstack.h"
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+struct hash_entry;
|
||||
+
|
||||
+typedef struct hash_table
|
||||
+{
|
||||
+ size_t size; /* Number of allocated entries. */
|
||||
+ size_t filled; /* Number of used entries. */
|
||||
+ struct hash_entry *first; /* Pointer to head of list of entries. */
|
||||
+ struct hash_entry *table; /* Pointer to array of entries. */
|
||||
+ struct obstack mem_pool; /* Memory pool holding the keys. */
|
||||
+}
|
||||
+hash_table;
|
||||
+
|
||||
+/* Initialize a hash table. INIT_SIZE > 1 is the initial number of available
|
||||
+ entries.
|
||||
+ Return 0 always. */
|
||||
+extern int hash_init (hash_table *htab, size_t init_size);
|
||||
+
|
||||
+/* Delete a hash table's contents.
|
||||
+ Return 0 always. */
|
||||
+extern int hash_destroy (hash_table *htab);
|
||||
+
|
||||
+/* Look up the value of a key in the given table.
|
||||
+ If found, return 0 and set *RESULT to it. Otherwise return -1. */
|
||||
+extern int hash_find_entry (const hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ void **result);
|
||||
+
|
||||
+/* Try to insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
|
||||
+ Return non-NULL (more precisely, the address of the KEY inside the table's
|
||||
+ memory pool) if successful, or NULL if there is already an entry with the
|
||||
+ given key. */
|
||||
+extern const void * hash_insert_entry (hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ void *data);
|
||||
+
|
||||
+/* Insert the pair (KEY[0..KEYLEN-1], DATA) in the hash table.
|
||||
+ Return 0. */
|
||||
+extern int hash_set_value (hash_table *htab,
|
||||
+ const void *key, size_t keylen,
|
||||
+ void *data);
|
||||
+
|
||||
+/* Steps *PTR forward to the next used entry in the given hash table. *PTR
|
||||
+ should be initially set to NULL. Store information about the next entry
|
||||
+ in *KEY, *KEYLEN, *DATA.
|
||||
+ Return 0 normally, -1 when the whole hash table has been traversed. */
|
||||
+extern int hash_iterate (hash_table *htab, void **ptr,
|
||||
+ const void **key, size_t *keylen,
|
||||
+ void **data);
|
||||
+
|
||||
+/* Steps *PTR forward to the next used entry in the given hash table. *PTR
|
||||
+ should be initially set to NULL. Store information about the next entry
|
||||
+ in *KEY, *KEYLEN, *DATAP. *DATAP is set to point to the storage of the
|
||||
+ value; modifying **DATAP will modify the value of the entry.
|
||||
+ Return 0 normally, -1 when the whole hash table has been traversed. */
|
||||
+extern int hash_iterate_modify (hash_table *htab, void **ptr,
|
||||
+ const void **key, size_t *keylen,
|
||||
+ void ***datap);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* not _GL_MEM_HASH_MAP_H */
|
||||
--- /dev/null
|
||||
+++ b/modules/mem-hash-map
|
||||
@@ -0,0 +1,25 @@
|
||||
+Description:
|
||||
+Simple hash table (no removals) where the keys are memory blocks.
|
||||
+
|
||||
+Files:
|
||||
+lib/mem-hash-map.h
|
||||
+lib/mem-hash-map.c
|
||||
+
|
||||
+Depends-on:
|
||||
+next-prime
|
||||
+obstack
|
||||
+xalloc
|
||||
+
|
||||
+configure.ac:
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += mem-hash-map.h mem-hash-map.c
|
||||
+
|
||||
+Include:
|
||||
+"mem-hash-map.h"
|
||||
+
|
||||
+License:
|
||||
+GPL
|
||||
+
|
||||
+Maintainer:
|
||||
+Bruno Haible
|
218
tools/gnulib/patches/645-next-prime.patch
Normal file
218
tools/gnulib/patches/645-next-prime.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From 0b953ba82830f51ce9b939700705d238f9b0c0ba Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 30 Apr 2025 01:52:17 +0200
|
||||
Subject: [PATCH] New module next-prime.
|
||||
|
||||
* lib/next-prime.h: New file, based on lib/hash.c.
|
||||
* lib/next-prime.c: New file, based on lib/hash.c.
|
||||
* modules/next-prime: New file.
|
||||
* lib/hash.c: Include next-prime.h.
|
||||
(is_prime, next_prime): Remove functions.
|
||||
* modules/hash (Depends-on): Add next-prime.
|
||||
---
|
||||
ChangeLog | 10 +++++++++
|
||||
lib/hash.c | 39 +-------------------------------
|
||||
lib/next-prime.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/next-prime.h | 41 +++++++++++++++++++++++++++++++++
|
||||
modules/hash | 1 +
|
||||
modules/next-prime | 24 ++++++++++++++++++++
|
||||
6 files changed, 133 insertions(+), 38 deletions(-)
|
||||
create mode 100644 lib/next-prime.c
|
||||
create mode 100644 lib/next-prime.h
|
||||
create mode 100644 modules/next-prime
|
||||
|
||||
--- a/lib/hash.c
|
||||
+++ b/lib/hash.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "hash.h"
|
||||
|
||||
#include "bitrotate.h"
|
||||
+#include "next-prime.h"
|
||||
#include "xalloc-oversized.h"
|
||||
|
||||
#include <errno.h>
|
||||
@@ -390,44 +391,6 @@ hash_string (const char *string, size_t
|
||||
|
||||
#endif /* not USE_DIFF_HASH */
|
||||
|
||||
-/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
|
||||
- number at least equal to 11. */
|
||||
-
|
||||
-static bool _GL_ATTRIBUTE_CONST
|
||||
-is_prime (size_t candidate)
|
||||
-{
|
||||
- size_t divisor = 3;
|
||||
- size_t square = divisor * divisor;
|
||||
-
|
||||
- while (square < candidate && (candidate % divisor))
|
||||
- {
|
||||
- divisor++;
|
||||
- square += 4 * divisor;
|
||||
- divisor++;
|
||||
- }
|
||||
-
|
||||
- return (candidate % divisor ? true : false);
|
||||
-}
|
||||
-
|
||||
-/* Round a given CANDIDATE number up to the nearest prime, and return that
|
||||
- prime. Primes lower than 10 are merely skipped. */
|
||||
-
|
||||
-static size_t _GL_ATTRIBUTE_CONST
|
||||
-next_prime (size_t candidate)
|
||||
-{
|
||||
- /* Skip small primes. */
|
||||
- if (candidate < 10)
|
||||
- candidate = 10;
|
||||
-
|
||||
- /* Make it definitely odd. */
|
||||
- candidate |= 1;
|
||||
-
|
||||
- while (SIZE_MAX != candidate && !is_prime (candidate))
|
||||
- candidate += 2;
|
||||
-
|
||||
- return candidate;
|
||||
-}
|
||||
-
|
||||
void
|
||||
hash_reset_tuning (Hash_tuning *tuning)
|
||||
{
|
||||
--- /dev/null
|
||||
+++ b/lib/next-prime.c
|
||||
@@ -0,0 +1,56 @@
|
||||
+/* Finding the next prime >= a given small integer.
|
||||
+ Copyright (C) 1995-2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include "next-prime.h"
|
||||
+
|
||||
+#include <stdint.h> /* for SIZE_MAX */
|
||||
+
|
||||
+/* Return true if CANDIDATE is a prime number. CANDIDATE should be an odd
|
||||
+ number at least equal to 11. */
|
||||
+static bool _GL_ATTRIBUTE_CONST
|
||||
+is_prime (size_t candidate)
|
||||
+{
|
||||
+ size_t divisor = 3;
|
||||
+ size_t square = divisor * divisor;
|
||||
+
|
||||
+ while (square < candidate && (candidate % divisor))
|
||||
+ {
|
||||
+ divisor++;
|
||||
+ square += 4 * divisor;
|
||||
+ divisor++;
|
||||
+ }
|
||||
+
|
||||
+ return (candidate % divisor ? true : false);
|
||||
+}
|
||||
+
|
||||
+size_t _GL_ATTRIBUTE_CONST
|
||||
+next_prime (size_t candidate)
|
||||
+{
|
||||
+ /* Skip small primes. */
|
||||
+ if (candidate < 10)
|
||||
+ candidate = 10;
|
||||
+
|
||||
+ /* Make it definitely odd. */
|
||||
+ candidate |= 1;
|
||||
+
|
||||
+ while (SIZE_MAX != candidate && !is_prime (candidate))
|
||||
+ candidate += 2;
|
||||
+
|
||||
+ return candidate;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/lib/next-prime.h
|
||||
@@ -0,0 +1,41 @@
|
||||
+/* Finding the next prime >= a given small integer.
|
||||
+ Copyright (C) 1995-2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _GL_NEXT_PRIME_H
|
||||
+#define _GL_NEXT_PRIME_H
|
||||
+
|
||||
+/* This file uses _GL_ATTRIBUTE_CONST. */
|
||||
+#if !_GL_CONFIG_H_INCLUDED
|
||||
+ #error "Please include config.h first."
|
||||
+#endif
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+/* Round a given CANDIDATE number up to the nearest prime, and return that
|
||||
+ prime. Primes lower than 10 are merely skipped. */
|
||||
+extern size_t _GL_ATTRIBUTE_CONST next_prime (size_t candidate);
|
||||
+
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _GL_NEXT_PRIME_H */
|
||||
--- a/modules/hash
|
||||
+++ b/modules/hash
|
||||
@@ -10,6 +10,7 @@ bitrotate
|
||||
calloc-posix
|
||||
free-posix
|
||||
malloc-posix
|
||||
+next-prime
|
||||
bool
|
||||
stdint-h
|
||||
xalloc-oversized
|
||||
--- /dev/null
|
||||
+++ b/modules/next-prime
|
||||
@@ -0,0 +1,24 @@
|
||||
+Description:
|
||||
+Finding the next prime >= a given small integer.
|
||||
+
|
||||
+Files:
|
||||
+lib/next-prime.h
|
||||
+lib/next-prime.c
|
||||
+
|
||||
+Depends-on:
|
||||
+bool
|
||||
+stdint-h
|
||||
+
|
||||
+configure.ac:
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += next-prime.h next-prime.c
|
||||
+
|
||||
+Include:
|
||||
+"next-prime.h"
|
||||
+
|
||||
+License:
|
||||
+LGPLv2+
|
||||
+
|
||||
+Maintainer:
|
||||
+all
|
294
tools/gnulib/patches/646-hashcode-string.patch
Normal file
294
tools/gnulib/patches/646-hashcode-string.patch
Normal file
@ -0,0 +1,294 @@
|
||||
From 64042bb91aea5f854ca8a8938e2b3f7d1935e4f1 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 30 Apr 2025 12:47:37 +0200
|
||||
Subject: [PATCH] New module hashcode-string1.
|
||||
|
||||
* lib/hashcode-string1.h: New file.
|
||||
* lib/hashcode-string1.c: New file, based on lib/hash.c.
|
||||
* modules/hashcode-string1: New file.
|
||||
* lib/hash.h: Include hashcode-string1.h.
|
||||
(hash_string): Remove declaration.
|
||||
* lib/hash.c (hash_string): Remove function.
|
||||
* modules/hash (Depends-on): Add hashcode-string1.
|
||||
* lib/exclude.c: Include hashcode-string1.h.
|
||||
* modules/exclude (Depends-on): Add hashcode-string1.
|
||||
---
|
||||
ChangeLog | 13 +++++++++
|
||||
lib/exclude.c | 1 +
|
||||
lib/hash.c | 59 ++++++--------------------------------
|
||||
lib/hash.h | 11 +++----
|
||||
lib/hashcode-string1.c | 62 ++++++++++++++++++++++++++++++++++++++++
|
||||
lib/hashcode-string1.h | 38 ++++++++++++++++++++++++
|
||||
modules/exclude | 1 +
|
||||
modules/hash | 1 +
|
||||
modules/hashcode-string1 | 24 ++++++++++++++++
|
||||
9 files changed, 154 insertions(+), 56 deletions(-)
|
||||
create mode 100644 lib/hashcode-string1.c
|
||||
create mode 100644 lib/hashcode-string1.h
|
||||
create mode 100644 modules/hashcode-string1
|
||||
|
||||
--- a/lib/exclude.c
|
||||
+++ b/lib/exclude.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "filename.h"
|
||||
#include <fnmatch.h>
|
||||
#include "hash.h"
|
||||
+#include "hashcode-string1.h"
|
||||
#if GNULIB_MCEL_PREFER
|
||||
# include "mcel.h"
|
||||
#else
|
||||
--- a/lib/hash.c
|
||||
+++ b/lib/hash.c
|
||||
@@ -345,57 +345,6 @@ hash_do_for_each (const Hash_table *tabl
|
||||
return counter;
|
||||
}
|
||||
|
||||
-/* Allocation and clean-up. */
|
||||
-
|
||||
-#if USE_DIFF_HASH
|
||||
-
|
||||
-/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
|
||||
- B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
|
||||
- Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
|
||||
- algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
|
||||
- may not be good for your application." */
|
||||
-
|
||||
-size_t
|
||||
-hash_string (const char *string, size_t n_buckets)
|
||||
-{
|
||||
-# define HASH_ONE_CHAR(Value, Byte) \
|
||||
- ((Byte) + rotl_sz (Value, 7))
|
||||
-
|
||||
- size_t value = 0;
|
||||
- unsigned char ch;
|
||||
-
|
||||
- for (; (ch = *string); string++)
|
||||
- value = HASH_ONE_CHAR (value, ch);
|
||||
- return value % n_buckets;
|
||||
-
|
||||
-# undef HASH_ONE_CHAR
|
||||
-}
|
||||
-
|
||||
-#else /* not USE_DIFF_HASH */
|
||||
-
|
||||
-/* This one comes from 'recode', and performs a bit better than the above as
|
||||
- per a few experiments. It is inspired from a hashing routine found in the
|
||||
- very old Cyber 'snoop', itself written in typical Greg Mansfield style.
|
||||
- (By the way, what happened to this excellent man? Is he still alive?) */
|
||||
-
|
||||
-size_t
|
||||
-hash_string (const char *string, size_t n_buckets)
|
||||
-{
|
||||
- size_t value = 0;
|
||||
- unsigned char ch;
|
||||
-
|
||||
- for (; (ch = *string); string++)
|
||||
- value = (value * 31 + ch) % n_buckets;
|
||||
- return value;
|
||||
-}
|
||||
-
|
||||
-#endif /* not USE_DIFF_HASH */
|
||||
-
|
||||
-void
|
||||
-hash_reset_tuning (Hash_tuning *tuning)
|
||||
-{
|
||||
- *tuning = default_tuning;
|
||||
-}
|
||||
|
||||
/* If the user passes a NULL hasher, we hash the raw pointer. */
|
||||
static size_t
|
||||
@@ -418,6 +367,14 @@ raw_comparator (const void *a, const voi
|
||||
}
|
||||
|
||||
|
||||
+/* Allocation and clean-up. */
|
||||
+
|
||||
+void
|
||||
+hash_reset_tuning (Hash_tuning *tuning)
|
||||
+{
|
||||
+ *tuning = default_tuning;
|
||||
+}
|
||||
+
|
||||
/* For the given hash TABLE, check the user supplied tuning structure for
|
||||
reasonable values, and return true if there is no gross error with it.
|
||||
Otherwise, definitively reset the TUNING field to some acceptable default
|
||||
--- a/lib/hash.h
|
||||
+++ b/lib/hash.h
|
||||
@@ -134,11 +134,6 @@ extern size_t hash_do_for_each (const Ha
|
||||
* Allocation and clean-up.
|
||||
*/
|
||||
|
||||
-/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
|
||||
- This is a convenience routine for constructing other hashing functions. */
|
||||
-extern size_t hash_string (const char *string, size_t n_buckets)
|
||||
- _GL_ATTRIBUTE_PURE;
|
||||
-
|
||||
extern void hash_reset_tuning (Hash_tuning *tuning);
|
||||
|
||||
typedef size_t (*Hash_hasher) (const void *entry, size_t table_size);
|
||||
@@ -266,6 +261,12 @@ extern void *hash_remove (Hash_table *ta
|
||||
_GL_ATTRIBUTE_DEPRECATED
|
||||
extern void *hash_delete (Hash_table *table, const void *entry);
|
||||
|
||||
+
|
||||
+# if GNULIB_HASHCODE_STRING1
|
||||
+/* Include declarations of module 'hashcode-string1'. */
|
||||
+# include "hashcode-string1.h"
|
||||
+# endif
|
||||
+
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
--- /dev/null
|
||||
+++ b/lib/hashcode-string1.c
|
||||
@@ -0,0 +1,62 @@
|
||||
+/* hashcode-string1.c -- compute a hash value from a NUL-terminated string.
|
||||
+
|
||||
+ Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include "hashcode-string1.h"
|
||||
+
|
||||
+#if USE_DIFF_HASH
|
||||
+
|
||||
+# include "bitrotate.h"
|
||||
+
|
||||
+/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
|
||||
+ B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
|
||||
+ Software--practice & experience 20, 2 (Feb 1990), 209-224. Good hash
|
||||
+ algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
|
||||
+ may not be good for your application." */
|
||||
+
|
||||
+size_t
|
||||
+hash_string (const char *string, size_t tablesize)
|
||||
+{
|
||||
+ size_t value = 0;
|
||||
+ unsigned char ch;
|
||||
+
|
||||
+ for (; (ch = *string); string++)
|
||||
+ value = ch + rotl_sz (value, 7);
|
||||
+ return value % tablesize;
|
||||
+}
|
||||
+
|
||||
+#else /* not USE_DIFF_HASH */
|
||||
+
|
||||
+/* This one comes from 'recode', and performs a bit better than the above as
|
||||
+ per a few experiments. It is inspired from a hashing routine found in the
|
||||
+ very old Cyber 'snoop', itself written in typical Greg Mansfield style.
|
||||
+ (By the way, what happened to this excellent man? Is he still alive?) */
|
||||
+
|
||||
+size_t
|
||||
+hash_string (const char *string, size_t tablesize)
|
||||
+{
|
||||
+ size_t value = 0;
|
||||
+ unsigned char ch;
|
||||
+
|
||||
+ for (; (ch = *string); string++)
|
||||
+ value = (value * 31 + ch) % tablesize;
|
||||
+ return value;
|
||||
+}
|
||||
+
|
||||
+#endif /* not USE_DIFF_HASH */
|
||||
--- /dev/null
|
||||
+++ b/lib/hashcode-string1.h
|
||||
@@ -0,0 +1,38 @@
|
||||
+/* hashcode-string1.h -- declaration for a simple hash function
|
||||
+ Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* This file uses _GL_ATTRIBUTE_PURE. */
|
||||
+#if !_GL_CONFIG_H_INCLUDED
|
||||
+ #error "Please include config.h first."
|
||||
+#endif
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+/* Compute a hash code for a NUL-terminated string S,
|
||||
+ and return the hash code modulo TABLESIZE.
|
||||
+ The result is platform dependent: it depends on the size of the 'size_t'
|
||||
+ type. */
|
||||
+extern size_t hash_string (char const *s, size_t tablesize) _GL_ATTRIBUTE_PURE;
|
||||
+
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
--- a/modules/exclude
|
||||
+++ b/modules/exclude
|
||||
@@ -12,6 +12,7 @@ filename
|
||||
fnmatch
|
||||
fopen-gnu
|
||||
hash
|
||||
+hashcode-string1
|
||||
mbscasecmp
|
||||
mbuiter [test "$GNULIB_MCEL_PREFER" != yes]
|
||||
nullptr
|
||||
--- a/modules/hash
|
||||
+++ b/modules/hash
|
||||
@@ -14,6 +14,7 @@ next-prime
|
||||
bool
|
||||
stdint-h
|
||||
xalloc-oversized
|
||||
+hashcode-string1
|
||||
|
||||
configure.ac:
|
||||
|
||||
--- /dev/null
|
||||
+++ b/modules/hashcode-string1
|
||||
@@ -0,0 +1,24 @@
|
||||
+Description:
|
||||
+Compute a hash value for a NUL-terminated string.
|
||||
+
|
||||
+Files:
|
||||
+lib/hashcode-string1.h
|
||||
+lib/hashcode-string1.c
|
||||
+
|
||||
+Depends-on:
|
||||
+bitrotate
|
||||
+
|
||||
+configure.ac:
|
||||
+gl_MODULE_INDICATOR([hashcode-string1])
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += hashcode-string1.h hashcode-string1.c
|
||||
+
|
||||
+Include:
|
||||
+"hashcode-string1.h"
|
||||
+
|
||||
+License:
|
||||
+LGPLv2+
|
||||
+
|
||||
+Maintainer:
|
||||
+Jim Meyering
|
215
tools/gnulib/patches/647-hashkey-string.patch
Normal file
215
tools/gnulib/patches/647-hashkey-string.patch
Normal file
@ -0,0 +1,215 @@
|
||||
From 52738dcd0f522b16653cc8b21adfcb758702f2ab Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 30 Apr 2025 01:20:17 +0200
|
||||
Subject: [PATCH] New module hashkey-string.
|
||||
|
||||
* lib/hashkey-string.h: New file.
|
||||
* lib/hashkey-string.c: New file, based on lib/clean-temp-simple.c.
|
||||
* modules/hashkey-string: New file.
|
||||
* lib/clean-temp-simple.c: Include hashkey-string.h. Don't include
|
||||
<limits.h>.
|
||||
(clean_temp_string_equals, clean_temp_string_hash): Remove functions.
|
||||
(SIZE_BITS): Remove macro.
|
||||
(register_temporary_file): Use hashkey_string_equals and
|
||||
hashkey_string_hash.
|
||||
* modules/clean-temp-simple (Depends-on): Add hashkey-string.
|
||||
---
|
||||
ChangeLog | 14 ++++++++++++
|
||||
lib/clean-temp-simple.c | 33 +++------------------------
|
||||
lib/hashkey-string.c | 48 +++++++++++++++++++++++++++++++++++++++
|
||||
lib/hashkey-string.h | 35 ++++++++++++++++++++++++++++
|
||||
modules/clean-temp-simple | 1 +
|
||||
modules/hashkey-string | 23 +++++++++++++++++++
|
||||
6 files changed, 124 insertions(+), 30 deletions(-)
|
||||
create mode 100644 lib/hashkey-string.c
|
||||
create mode 100644 lib/hashkey-string.h
|
||||
create mode 100644 modules/hashkey-string
|
||||
|
||||
--- a/lib/clean-temp-simple.c
|
||||
+++ b/lib/clean-temp-simple.c
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "clean-temp-private.h"
|
||||
|
||||
#include <errno.h>
|
||||
-#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -36,6 +35,7 @@
|
||||
#include "thread-optim.h"
|
||||
#include "gl_list.h"
|
||||
#include "gl_linkedhash_list.h"
|
||||
+#include "hashkey-string.h"
|
||||
#include "gettext.h"
|
||||
|
||||
#define _(msgid) dgettext ("gnulib", msgid)
|
||||
@@ -106,33 +106,6 @@ gl_list_t /* <closeable_fd *> */ volatil
|
||||
asynchronous signal.
|
||||
*/
|
||||
|
||||
-/* String equality and hash code functions used by the lists. */
|
||||
-
|
||||
-bool
|
||||
-clean_temp_string_equals (const void *x1, const void *x2)
|
||||
-{
|
||||
- const char *s1 = (const char *) x1;
|
||||
- const char *s2 = (const char *) x2;
|
||||
- return strcmp (s1, s2) == 0;
|
||||
-}
|
||||
-
|
||||
-#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
|
||||
-
|
||||
-/* A hash function for NUL-terminated char* strings using
|
||||
- the method described by Bruno Haible.
|
||||
- See https://www.haible.de/bruno/hashfunc.html. */
|
||||
-size_t
|
||||
-clean_temp_string_hash (const void *x)
|
||||
-{
|
||||
- const char *s = (const char *) x;
|
||||
- size_t h = 0;
|
||||
-
|
||||
- for (; *s; s++)
|
||||
- h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
|
||||
-
|
||||
- return h;
|
||||
-}
|
||||
-
|
||||
|
||||
/* The set of fatal signal handlers.
|
||||
Cached here because we are not allowed to call get_fatal_signal_set ()
|
||||
@@ -326,8 +299,8 @@ register_temporary_file (const char *abs
|
||||
}
|
||||
file_cleanup_list =
|
||||
gl_list_nx_create_empty (GL_LINKEDHASH_LIST,
|
||||
- clean_temp_string_equals,
|
||||
- clean_temp_string_hash,
|
||||
+ hashkey_string_equals,
|
||||
+ hashkey_string_hash,
|
||||
NULL, false);
|
||||
if (file_cleanup_list == NULL)
|
||||
{
|
||||
--- /dev/null
|
||||
+++ b/lib/hashkey-string.c
|
||||
@@ -0,0 +1,48 @@
|
||||
+/* Support for using a string as a hash key.
|
||||
+ Copyright (C) 2006-2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include "hashkey-string.h"
|
||||
+
|
||||
+#include <limits.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+bool
|
||||
+hashkey_string_equals (const void *x1, const void *x2)
|
||||
+{
|
||||
+ const char *s1 = (const char *) x1;
|
||||
+ const char *s2 = (const char *) x2;
|
||||
+ return strcmp (s1, s2) == 0;
|
||||
+}
|
||||
+
|
||||
+#define SIZE_BITS (sizeof (size_t) * CHAR_BIT)
|
||||
+
|
||||
+/* A hash function for NUL-terminated 'const char *' strings using
|
||||
+ the method described by Bruno Haible.
|
||||
+ See https://www.haible.de/bruno/hashfunc.html. */
|
||||
+size_t
|
||||
+hashkey_string_hash (const void *x)
|
||||
+{
|
||||
+ const char *s = (const char *) x;
|
||||
+ size_t h = 0;
|
||||
+
|
||||
+ for (; *s; s++)
|
||||
+ h = *s + ((h << 9) | (h >> (SIZE_BITS - 9)));
|
||||
+
|
||||
+ return h;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/lib/hashkey-string.h
|
||||
@@ -0,0 +1,35 @@
|
||||
+/* Support for using a string as a hash key.
|
||||
+ Copyright (C) 2006-2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser General Public License as
|
||||
+ published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _GL_HASHKEY_STRING_H
|
||||
+#define _GL_HASHKEY_STRING_H
|
||||
+
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+/* String equality and hash code functions that operate on plain C strings
|
||||
+ ('const char *'). */
|
||||
+extern bool hashkey_string_equals (const void *x1, const void *x2);
|
||||
+extern size_t hashkey_string_hash (const void *x);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _GL_HASHKEY_STRING_H */
|
||||
--- a/modules/clean-temp-simple
|
||||
+++ b/modules/clean-temp-simple
|
||||
@@ -19,6 +19,7 @@ error
|
||||
fatal-signal
|
||||
rmdir
|
||||
linkedhash-list
|
||||
+hashkey-string
|
||||
gettext-h
|
||||
gnulib-i18n
|
||||
|
||||
--- /dev/null
|
||||
+++ b/modules/hashkey-string
|
||||
@@ -0,0 +1,23 @@
|
||||
+Description:
|
||||
+Support for using a string as a hash key in the hash-set and hash-map modules.
|
||||
+
|
||||
+Files:
|
||||
+lib/hashkey-string.h
|
||||
+lib/hashkey-string.c
|
||||
+
|
||||
+Depends-on:
|
||||
+bool
|
||||
+
|
||||
+configure.ac:
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += hashkey-string.h hashkey-string.c
|
||||
+
|
||||
+Include:
|
||||
+"hashkey-string.h"
|
||||
+
|
||||
+License:
|
||||
+LGPLv2+
|
||||
+
|
||||
+Maintainer:
|
||||
+all
|
176
tools/gnulib/patches/650-package-version.patch
Normal file
176
tools/gnulib/patches/650-package-version.patch
Normal file
@ -0,0 +1,176 @@
|
||||
From e518788ad085e02b046e42889039a1f671e4619a Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 22 Jan 2025 21:21:59 +0100
|
||||
Subject: New module 'package-version'.
|
||||
|
||||
* m4/init-package-version.m4: New file, from GNU libunistring.
|
||||
* modules/package-version: New file.
|
||||
* modules/git-version-gen (Depends-on): Add it.
|
||||
---
|
||||
ChangeLog | 7 +++
|
||||
m4/init-package-version.m4 | 124 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
modules/git-version-gen | 1 +
|
||||
modules/package-version | 19 +++++++
|
||||
4 files changed, 151 insertions(+)
|
||||
create mode 100644 m4/init-package-version.m4
|
||||
create mode 100644 modules/package-version
|
||||
|
||||
--- /dev/null
|
||||
+++ b/m4/init-package-version.m4
|
||||
@@ -0,0 +1,124 @@
|
||||
+# init-package-version.m4
|
||||
+# serial 3
|
||||
+dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
|
||||
+dnl This file is free software, distributed under the terms of the GNU
|
||||
+dnl General Public License. As a special exception to the GNU General
|
||||
+dnl Public License, this file may be distributed as part of a program
|
||||
+dnl that contains a configuration script generated by Autoconf, under
|
||||
+dnl the same distribution terms as the rest of that program.
|
||||
+
|
||||
+# Make it possible to pass version numbers extracted from a file in
|
||||
+# $(srcdir) to autoconf.
|
||||
+#
|
||||
+# Autoconf insists on passing the package name and version number to
|
||||
+# every generated .h file and every Makefile. This was a reasonable
|
||||
+# design at times when a version number was changed only once a month.
|
||||
+# Nowadays, people often assign a new version number once a week, or
|
||||
+# even change it each time a 'git' commit is made. Regenerating all
|
||||
+# the files that depend on configure.ac (aclocal.m4, configure,
|
||||
+# config.status, config.h, all Makefiles) may take 15 minutes. These
|
||||
+# delays can severely hamper development.
|
||||
+#
|
||||
+# An alternative is to store the version number in a file in $(srcdir)
|
||||
+# that is separate from configure.ac. It can be a data file, a shell
|
||||
+# script, a .m4 file, or other. The essential point is that the maintainer
|
||||
+# is responsible for creating Makefile dependencies to this version file
|
||||
+# for every file that needs to be rebuilt when the version changes. This
|
||||
+# typically includes
|
||||
+# - distributable documentation files that carry the version number,
|
||||
+# but does not include
|
||||
+# - aclocal.m4, configure, config.status, config.h, all Makefiles,
|
||||
+# - executables.
|
||||
+#
|
||||
+# autoconf and automake make it hard to follow this approach:
|
||||
+#
|
||||
+# - If AC_INIT is used with arguments, there is a chicken-and-egg problem:
|
||||
+# The arguments need to be read from a file in $(srcdir). The location
|
||||
+# of $(srcdir) is only determined by AC_CONFIG_SRCDIR. AC_CONFIG_SRCDIR
|
||||
+# can only appear after AC_INIT (otherwise aclocal gives an error:
|
||||
+# "error: m4_defn: undefined macro: _m4_divert_diversion").
|
||||
+# Furthermore, the arguments passed to AC_INIT must be literals; for
|
||||
+# example, the assignment to PACKAGE_VERSION looks like this:
|
||||
+# [PACKAGE_VERSION=']AC_PACKAGE_VERSION[']
|
||||
+#
|
||||
+# - If AC_INIT is used without arguments:
|
||||
+# Automake provides its own variables, PACKAGE and VERSION, and uses them
|
||||
+# instead of PACKAGE_NAME and PACKAGE_VERSION that come from Autoconf.
|
||||
+# - If AM_INIT_AUTOMAKE is used with two arguments, automake options
|
||||
+# like 'silent-rules' cannot be specified.
|
||||
+# - If AM_INIT_AUTOMAKE is used in its one-argument form or without
|
||||
+# arguments at all, it triggers an error
|
||||
+# "error: AC_INIT should be called with package and version arguments".
|
||||
+# - If AM_INIT_AUTOMAKE is used in its one-argument form or without
|
||||
+# arguments at all, and _AC_INIT_PACKAGE is used before it, with
|
||||
+# the package and version number from the file as arguments, we get
|
||||
+# a warning: "warning: AC_INIT: not a literal: $VERSION_NUMBER".
|
||||
+# The arguments passed to _AC_INIT_PACKAGE must be literals.
|
||||
+#
|
||||
+# With the macro defined in this file, the approach can be coded like this:
|
||||
+#
|
||||
+# AC_INIT
|
||||
+# AC_CONFIG_SRCDIR(WITNESS)
|
||||
+# . $srcdir/../version.sh
|
||||
+# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER)
|
||||
+# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
+#
|
||||
+# and after changing version.sh, the developer can directly configure and build:
|
||||
+#
|
||||
+# make distclean
|
||||
+# ./configure
|
||||
+# make
|
||||
+#
|
||||
+# Some other packages use another approach:
|
||||
+#
|
||||
+# AC_INIT(PACKAGE,
|
||||
+# m4_normalize(m4_esyscmd([. ./version.sh; echo $VERSION_NUMBER])))
|
||||
+# AC_CONFIG_SRCDIR(WITNESS)
|
||||
+# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
+#
|
||||
+# but here, after changing version.sh, the developer must first regenerate the
|
||||
+# configure file:
|
||||
+#
|
||||
+# make distclean
|
||||
+# ./autogen.sh --skip-gnulib
|
||||
+# ./configure
|
||||
+# make
|
||||
+#
|
||||
+
|
||||
+# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION)
|
||||
+# --------------------------------------
|
||||
+# followed by an AM_INIT_AUTOMAKE invocation,
|
||||
+# is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION)
|
||||
+# except that it can use computed non-literal arguments.
|
||||
+AC_DEFUN([gl_INIT_PACKAGE],
|
||||
+[
|
||||
+ AC_BEFORE([$0], [AM_INIT_AUTOMAKE])
|
||||
+ dnl Redefine AM_INIT_AUTOMAKE.
|
||||
+ m4_define([gl_AM_INIT_AUTOMAKE],
|
||||
+ m4_bpatsubst(m4_dquote(
|
||||
+ m4_bpatsubst(m4_dquote(
|
||||
+ m4_bpatsubst(m4_dquote(
|
||||
+ m4_defn([AM_INIT_AUTOMAKE])),
|
||||
+ [AC_PACKAGE_NAME], [gl_INIT_DUMMY])),
|
||||
+ [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])),
|
||||
+ [AC_PACKAGE_VERSION], [gl_INIT_DUMMY])
|
||||
+ [AC_SUBST([PACKAGE], [$1])
|
||||
+ AC_SUBST([VERSION], [$2])
|
||||
+ ])
|
||||
+ m4_define([AM_INIT_AUTOMAKE],
|
||||
+ m4_defn([gl_RPL_INIT_AUTOMAKE]))
|
||||
+])
|
||||
+m4_define([gl_INIT_EMPTY], [])
|
||||
+dnl Automake 1.16.4 no longer accepts an empty value for gl_INIT_DUMMY.
|
||||
+dnl But a macro that later expands to empty works.
|
||||
+m4_define([gl_INIT_DUMMY], [gl_INIT_DUMMY2])
|
||||
+m4_define([gl_INIT_DUMMY2], [])
|
||||
+AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [
|
||||
+ m4_ifval([$2],
|
||||
+ [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
|
||||
+ gl_AM_INIT_AUTOMAKE([$1 no-define])
|
||||
+ m4_if(m4_index([ $1 ], [ no-define ]), [-1],
|
||||
+ [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])
|
||||
+ ])
|
||||
+])
|
||||
--- a/modules/git-version-gen
|
||||
+++ b/modules/git-version-gen
|
||||
@@ -5,6 +5,7 @@ Files:
|
||||
build-aux/git-version-gen
|
||||
|
||||
Depends-on:
|
||||
+package-version
|
||||
|
||||
configure.ac:
|
||||
|
||||
--- /dev/null
|
||||
+++ b/modules/package-version
|
||||
@@ -0,0 +1,19 @@
|
||||
+Description:
|
||||
+Support for a computed version string.
|
||||
+
|
||||
+Files:
|
||||
+m4/init-package-version.m4
|
||||
+
|
||||
+Depends-on:
|
||||
+
|
||||
+configure.ac:
|
||||
+
|
||||
+Makefile.am:
|
||||
+
|
||||
+Include:
|
||||
+
|
||||
+License:
|
||||
+GPLed build tool
|
||||
+
|
||||
+Maintainer:
|
||||
+Bruno Haible
|
66
tools/gnulib/patches/651-package-version-simplify.patch
Normal file
66
tools/gnulib/patches/651-package-version-simplify.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From bb0f82be83d43db9cd77049be32ffd0b92ab5bb7 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Fri, 24 Jan 2025 22:03:29 +0100
|
||||
Subject: package-version: Simplify its use.
|
||||
|
||||
Reported by Basil L. Contovounesios <basil@contovou.net> in
|
||||
<https://lists.gnu.org/archive/html/bug-gnulib/2025-01/msg00195.html>.
|
||||
|
||||
* doc/package-version.texi (Propagating the package version): Recommend
|
||||
to pass the usual arguments to AC_INIT.
|
||||
* m4/init-package-version.m4: Likewise.
|
||||
(gl_INIT_PACKAGE): Define PACKAGE_VERSION and PACKAGE_STRING as needed.
|
||||
(gl_RPL_INIT_AUTOMAKE): Improve quoting.
|
||||
---
|
||||
ChangeLog | 11 +++++++++++
|
||||
doc/package-version.texi | 2 +-
|
||||
m4/init-package-version.m4 | 20 ++++++++++++++------
|
||||
3 files changed, 26 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/m4/init-package-version.m4
|
||||
+++ b/m4/init-package-version.m4
|
||||
@@ -1,5 +1,5 @@
|
||||
# init-package-version.m4
|
||||
-# serial 3
|
||||
+# serial 4
|
||||
dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
|
||||
dnl This file is free software, distributed under the terms of the GNU
|
||||
dnl General Public License. As a special exception to the GNU General
|
||||
@@ -57,7 +57,7 @@ dnl the same distribution terms as the r
|
||||
#
|
||||
# With the macro defined in this file, the approach can be coded like this:
|
||||
#
|
||||
-# AC_INIT
|
||||
+# AC_INIT(PACKAGE, [dummy], [MORE OPTIONS])
|
||||
# AC_CONFIG_SRCDIR(WITNESS)
|
||||
# . $srcdir/../version.sh
|
||||
# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER)
|
||||
@@ -102,8 +102,16 @@ AC_DEFUN([gl_INIT_PACKAGE],
|
||||
[AC_PACKAGE_NAME], [gl_INIT_DUMMY])),
|
||||
[AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])),
|
||||
[AC_PACKAGE_VERSION], [gl_INIT_DUMMY])
|
||||
- [AC_SUBST([PACKAGE], [$1])
|
||||
- AC_SUBST([VERSION], [$2])
|
||||
+ [dnl Set variables documented in Automake.
|
||||
+ AC_SUBST([PACKAGE], [$1])
|
||||
+ AC_SUBST([VERSION], ["$2"])
|
||||
+ dnl Set variables documented in Autoconf.
|
||||
+ AC_SUBST([PACKAGE_VERSION], ["$2"])
|
||||
+ AC_SUBST([PACKAGE_STRING], ["$1 $2"])
|
||||
+ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$2"],
|
||||
+ [Define to the version of this package.])
|
||||
+ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$1 $2"],
|
||||
+ [Define to the full name and version of this package.])
|
||||
])
|
||||
m4_define([AM_INIT_AUTOMAKE],
|
||||
m4_defn([gl_RPL_INIT_AUTOMAKE]))
|
||||
@@ -118,7 +126,7 @@ AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [
|
||||
[m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
|
||||
gl_AM_INIT_AUTOMAKE([$1 no-define])
|
||||
m4_if(m4_index([ $1 ], [ no-define ]), [-1],
|
||||
- [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])
|
||||
+ [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
|
||||
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])
|
||||
])
|
||||
])
|
@ -0,0 +1,89 @@
|
||||
From 48648b4b9b3fd79a5c68913deb28678bd9d8eb34 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Sat, 25 Jan 2025 04:07:32 +0100
|
||||
Subject: package-version: Simplify further.
|
||||
|
||||
* doc/package-version.texi (Propagating the package version): Recommend
|
||||
use of gl_INIT_PACKAGE_VERSION instead of gl_INIT_PACKAGE.
|
||||
* build-aux/git-version-gen: Likewise.
|
||||
* m4/init-package-version.m4: Likewise.
|
||||
(gl_INIT_PACKAGE_VERSION): Renamed from gl_INIT_PACKAGE. Take only one
|
||||
argument. Don't fiddle with AC_PACKAGE_NAME, AC_PACKAGE_TARNAME,
|
||||
PACKAGE.
|
||||
(gl_RPL_INIT_AUTOMAKE): Update.
|
||||
---
|
||||
ChangeLog | 10 ++++++++++
|
||||
build-aux/git-version-gen | 4 ++--
|
||||
doc/package-version.texi | 4 ++--
|
||||
m4/init-package-version.m4 | 30 ++++++++++++------------------
|
||||
4 files changed, 26 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/m4/init-package-version.m4
|
||||
+++ b/m4/init-package-version.m4
|
||||
@@ -1,5 +1,5 @@
|
||||
# init-package-version.m4
|
||||
-# serial 4
|
||||
+# serial 5
|
||||
dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
|
||||
dnl This file is free software, distributed under the terms of the GNU
|
||||
dnl General Public License. As a special exception to the GNU General
|
||||
@@ -60,7 +60,7 @@ dnl the same distribution terms as the r
|
||||
# AC_INIT(PACKAGE, [dummy], [MORE OPTIONS])
|
||||
# AC_CONFIG_SRCDIR(WITNESS)
|
||||
# . $srcdir/../version.sh
|
||||
-# gl_INIT_PACKAGE(PACKAGE, $VERSION_NUMBER)
|
||||
+# gl_INIT_PACKAGE_VERSION($VERSION_NUMBER)
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
#
|
||||
# and after changing version.sh, the developer can directly configure and build:
|
||||
@@ -85,32 +85,26 @@ dnl the same distribution terms as the r
|
||||
# make
|
||||
#
|
||||
|
||||
-# gl_INIT_PACKAGE(PACKAGE-NAME, VERSION)
|
||||
-# --------------------------------------
|
||||
+# gl_INIT_PACKAGE_VERSION(VERSION)
|
||||
+# --------------------------------
|
||||
# followed by an AM_INIT_AUTOMAKE invocation,
|
||||
# is like calling AM_INIT_AUTOMAKE(PACKAGE-NAME, VERSION)
|
||||
# except that it can use computed non-literal arguments.
|
||||
-AC_DEFUN([gl_INIT_PACKAGE],
|
||||
+AC_DEFUN([gl_INIT_PACKAGE_VERSION],
|
||||
[
|
||||
AC_BEFORE([$0], [AM_INIT_AUTOMAKE])
|
||||
dnl Redefine AM_INIT_AUTOMAKE.
|
||||
m4_define([gl_AM_INIT_AUTOMAKE],
|
||||
- m4_bpatsubst(m4_dquote(
|
||||
- m4_bpatsubst(m4_dquote(
|
||||
- m4_bpatsubst(m4_dquote(
|
||||
- m4_defn([AM_INIT_AUTOMAKE])),
|
||||
- [AC_PACKAGE_NAME], [gl_INIT_DUMMY])),
|
||||
- [AC_PACKAGE_TARNAME], [gl_INIT_EMPTY])),
|
||||
+ m4_bpatsubst(m4_dquote(m4_defn([AM_INIT_AUTOMAKE])),
|
||||
[AC_PACKAGE_VERSION], [gl_INIT_DUMMY])
|
||||
[dnl Set variables documented in Automake.
|
||||
- AC_SUBST([PACKAGE], [$1])
|
||||
- AC_SUBST([VERSION], ["$2"])
|
||||
+ AC_SUBST([VERSION], ["$1"])
|
||||
dnl Set variables documented in Autoconf.
|
||||
- AC_SUBST([PACKAGE_VERSION], ["$2"])
|
||||
- AC_SUBST([PACKAGE_STRING], ["$1 $2"])
|
||||
- AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$2"],
|
||||
+ AC_SUBST([PACKAGE_VERSION], ["$1"])
|
||||
+ AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"])
|
||||
+ AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"],
|
||||
[Define to the version of this package.])
|
||||
- AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["$1 $2"],
|
||||
+ AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"],
|
||||
[Define to the full name and version of this package.])
|
||||
])
|
||||
m4_define([AM_INIT_AUTOMAKE],
|
||||
@@ -123,7 +117,7 @@ m4_define([gl_INIT_DUMMY], [gl_INIT_DUMM
|
||||
m4_define([gl_INIT_DUMMY2], [])
|
||||
AC_DEFUN([gl_RPL_INIT_AUTOMAKE], [
|
||||
m4_ifval([$2],
|
||||
- [m4_fatal([After gl_INIT_PACKAGE, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
|
||||
+ [m4_fatal([After gl_INIT_PACKAGE_VERSION, the two-argument form of AM_INIT_AUTOMAKE cannot be used.])])
|
||||
gl_AM_INIT_AUTOMAKE([$1 no-define])
|
||||
m4_if(m4_index([ $1 ], [ no-define ]), [-1],
|
||||
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
|
32
tools/gnulib/patches/653-package-version-warning.patch
Normal file
32
tools/gnulib/patches/653-package-version-warning.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 2e46209809f751087ca27523283bd5c3e9071d31 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Sun, 26 Jan 2025 13:26:35 +0100
|
||||
Subject: package-version: Avoid compiler warnings in config.log.
|
||||
|
||||
* m4/init-package-version.m4 (gl_INIT_PACKAGE_VERSION): Undefine
|
||||
PACKAGE_VERSION and PACKAGE_STRING before redefining them.
|
||||
---
|
||||
ChangeLog | 6 ++++++
|
||||
m4/init-package-version.m4 | 4 +++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/m4/init-package-version.m4
|
||||
+++ b/m4/init-package-version.m4
|
||||
@@ -1,5 +1,5 @@
|
||||
# init-package-version.m4
|
||||
-# serial 5
|
||||
+# serial 6
|
||||
dnl Copyright (C) 1992-2025 Free Software Foundation, Inc.
|
||||
dnl This file is free software, distributed under the terms of the GNU
|
||||
dnl General Public License. As a special exception to the GNU General
|
||||
@@ -102,8 +102,10 @@ AC_DEFUN([gl_INIT_PACKAGE_VERSION],
|
||||
dnl Set variables documented in Autoconf.
|
||||
AC_SUBST([PACKAGE_VERSION], ["$1"])
|
||||
AC_SUBST([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"])
|
||||
+ _AC_DEFINE([#undef PACKAGE_VERSION])
|
||||
AC_DEFINE_UNQUOTED([PACKAGE_VERSION], ["$1"],
|
||||
[Define to the version of this package.])
|
||||
+ _AC_DEFINE([#undef PACKAGE_STRING])
|
||||
AC_DEFINE_UNQUOTED([PACKAGE_STRING], ["AC_PACKAGE_NAME $1"],
|
||||
[Define to the full name and version of this package.])
|
||||
])
|
75
tools/gnulib/patches/660-version-stamp.patch
Normal file
75
tools/gnulib/patches/660-version-stamp.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 85599643e2fbf70f7f0bd58831993132ef335705 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 22 Jan 2025 21:25:27 +0100
|
||||
Subject: New module 'version-stamp'.
|
||||
|
||||
* m4/version-stamp.m4: New file.
|
||||
* modules/version-stamp: New file.
|
||||
---
|
||||
ChangeLog | 6 ++++++
|
||||
m4/version-stamp.m4 | 35 +++++++++++++++++++++++++++++++++++
|
||||
modules/version-stamp | 19 +++++++++++++++++++
|
||||
3 files changed, 60 insertions(+)
|
||||
create mode 100644 m4/version-stamp.m4
|
||||
create mode 100644 modules/version-stamp
|
||||
|
||||
--- /dev/null
|
||||
+++ b/m4/version-stamp.m4
|
||||
@@ -0,0 +1,35 @@
|
||||
+# version-stamp.m4
|
||||
+# serial 1
|
||||
+dnl Copyright (C) 2025 Free Software Foundation, Inc.
|
||||
+dnl This file is free software, distributed under the terms of the GNU
|
||||
+dnl General Public License. As a special exception to the GNU General
|
||||
+dnl Public License, this file may be distributed as part of a program
|
||||
+dnl that contains a configuration script generated by Autoconf, under
|
||||
+dnl the same distribution terms as the rest of that program.
|
||||
+
|
||||
+# Manages a stamp file, that keeps track when $(VERSION) was last changed.
|
||||
+#
|
||||
+# gl_CONFIG_VERSION_STAMP
|
||||
+# needs to be invoked near the end of the package's top-level configure.ac,
|
||||
+# before AC_OUTPUT.
|
||||
+# It makes sure that during the build,
|
||||
+# - $(top_srcdir)/.version exists, and
|
||||
+# - when $(VERSION) is changed, $(top_srcdir)/.version gets modified.
|
||||
+#
|
||||
+# $(top_srcdir)/.version is a stamp file. Its contents wouldn't matter,
|
||||
+# except that for detecting the change, we store the value of $(VERSION)
|
||||
+# in it (but we could just as well store it in a different file).
|
||||
+AC_DEFUN([gl_CONFIG_VERSION_STAMP],
|
||||
+[
|
||||
+ AC_CONFIG_COMMANDS([version-timestamp],
|
||||
+ [if test -f "$ac_top_srcdir/.version" \
|
||||
+ && test `cat "$ac_top_srcdir/.version"` = "$gl_version"; then
|
||||
+ # The value of $(VERSION) is the same as last time.
|
||||
+ :
|
||||
+ else
|
||||
+ # The value of $(VERSION) has changed. Update the stamp.
|
||||
+ echo "$gl_version" > "$ac_top_srcdir/.version"
|
||||
+ fi
|
||||
+ ],
|
||||
+ [gl_version="$VERSION"])
|
||||
+])
|
||||
--- /dev/null
|
||||
+++ b/modules/version-stamp
|
||||
@@ -0,0 +1,19 @@
|
||||
+Description:
|
||||
+Optimized rebuilding of artifacts that depend on $(VERSION).
|
||||
+
|
||||
+Files:
|
||||
+m4/version-stamp.m4
|
||||
+
|
||||
+Depends-on:
|
||||
+
|
||||
+configure.ac:
|
||||
+
|
||||
+Makefile.am:
|
||||
+
|
||||
+Include:
|
||||
+
|
||||
+License:
|
||||
+GPLed build tool
|
||||
+
|
||||
+Maintainer:
|
||||
+Bruno Haible
|
366
tools/gnulib/patches/689-vc-mtime.patch
Normal file
366
tools/gnulib/patches/689-vc-mtime.patch
Normal file
@ -0,0 +1,366 @@
|
||||
From 701d20aaf579bb71f35209dd63a272c3d9d21096 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Mon, 24 Feb 2025 19:03:17 +0100
|
||||
Subject: [PATCH] vc-mtime: New module.
|
||||
|
||||
* lib/vc-mtime.h: New file.
|
||||
* lib/vc-mtime.c: New file.
|
||||
* modules/vc-mtime: New file.
|
||||
---
|
||||
ChangeLog | 7 ++
|
||||
lib/vc-mtime.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/vc-mtime.h | 97 ++++++++++++++++++++++
|
||||
modules/vc-mtime | 34 ++++++++
|
||||
4 files changed, 346 insertions(+)
|
||||
create mode 100644 lib/vc-mtime.c
|
||||
create mode 100644 lib/vc-mtime.h
|
||||
create mode 100644 modules/vc-mtime
|
||||
|
||||
--- /dev/null
|
||||
+++ b/lib/vc-mtime.c
|
||||
@@ -0,0 +1,208 @@
|
||||
+/* Return the version-control based modification time of a file.
|
||||
+ Copyright (C) 2025 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 Bruno Haible <bruno@clisp.org>, 2025. */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include "vc-mtime.h"
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include <error.h>
|
||||
+#include "spawn-pipe.h"
|
||||
+#include "wait-process.h"
|
||||
+#include "execute.h"
|
||||
+#include "safe-read.h"
|
||||
+#include "xstrtol.h"
|
||||
+#include "stat-time.h"
|
||||
+#include "gettext.h"
|
||||
+
|
||||
+#define _(msgid) dgettext ("gnulib", msgid)
|
||||
+
|
||||
+
|
||||
+/* Determines whether the specified file is under version control. */
|
||||
+static bool
|
||||
+git_vc_controlled (const char *filename)
|
||||
+{
|
||||
+ /* Run "git ls-files FILENAME" and return true if the exit code is 0
|
||||
+ and the output is non-empty. */
|
||||
+ const char *argv[4];
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
+
|
||||
+ argv[0] = "git";
|
||||
+ argv[1] = "ls-files";
|
||||
+ argv[2] = filename;
|
||||
+ argv[3] = NULL;
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+ if (child == -1)
|
||||
+ return false;
|
||||
+
|
||||
+ /* Read the subprocess output, and test whether it is non-empty. */
|
||||
+ size_t count = 0;
|
||||
+ char c;
|
||||
+
|
||||
+ while (safe_read (fd[0], &c, 1) > 0)
|
||||
+ count++;
|
||||
+
|
||||
+ close (fd[0]);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit status. */
|
||||
+ int exitstatus =
|
||||
+ wait_subprocess (child, "git", false, true, true, false, NULL);
|
||||
+ return (exitstatus == 0 && count > 0);
|
||||
+}
|
||||
+
|
||||
+/* Determines whether the specified file is unmodified, compared to the
|
||||
+ last version in version control. */
|
||||
+static bool
|
||||
+git_unmodified (const char *filename)
|
||||
+{
|
||||
+ /* Run "git diff --quiet -- HEAD FILENAME"
|
||||
+ (or "git diff --quiet HEAD FILENAME")
|
||||
+ and return true if the exit code is 0.
|
||||
+ The '--' option is for the case that the specified file was removed. */
|
||||
+ const char *argv[7];
|
||||
+ int exitstatus;
|
||||
+
|
||||
+ argv[0] = "git";
|
||||
+ argv[1] = "diff";
|
||||
+ argv[2] = "--quiet";
|
||||
+ argv[3] = "--";
|
||||
+ argv[4] = "HEAD";
|
||||
+ argv[5] = filename;
|
||||
+ argv[6] = NULL;
|
||||
+ exitstatus = execute ("git", "git", argv, NULL, NULL,
|
||||
+ false, false, true, true,
|
||||
+ true, false, NULL);
|
||||
+ return (exitstatus == 0);
|
||||
+}
|
||||
+
|
||||
+/* Stores in *MTIME the time of last modification in version control of the
|
||||
+ specified file, and returns 0.
|
||||
+ Upon failure, it returns -1. */
|
||||
+static int
|
||||
+git_mtime (struct timespec *mtime, const char *filename)
|
||||
+{
|
||||
+ /* Run "git log -1 --format=%ct -- FILENAME". It prints the time of last
|
||||
+ modification, as the number of seconds since the Epoch.
|
||||
+ The '--' option is for the case that the specified file was removed. */
|
||||
+ const char *argv[7];
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
+
|
||||
+ argv[0] = "git";
|
||||
+ argv[1] = "log";
|
||||
+ argv[2] = "-1";
|
||||
+ argv[3] = "--format=%ct";
|
||||
+ argv[4] = "--";
|
||||
+ argv[5] = filename;
|
||||
+ argv[6] = NULL;
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+ if (child == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ /* Retrieve its result. */
|
||||
+ FILE *fp;
|
||||
+ char *line;
|
||||
+ size_t linesize;
|
||||
+ size_t linelen;
|
||||
+
|
||||
+ fp = fdopen (fd[0], "r");
|
||||
+ if (fp == NULL)
|
||||
+ error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
+
|
||||
+ line = NULL; linesize = 0;
|
||||
+ linelen = getline (&line, &linesize, fp);
|
||||
+ if (linelen == (size_t)(-1))
|
||||
+ {
|
||||
+ error (0, 0, _("%s subprocess I/O error"), "git");
|
||||
+ fclose (fp);
|
||||
+ wait_subprocess (child, "git", true, false, true, false, NULL);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ int exitstatus;
|
||||
+
|
||||
+ if (linelen > 0 && line[linelen - 1] == '\n')
|
||||
+ line[linelen - 1] = '\0';
|
||||
+
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit status. */
|
||||
+ exitstatus =
|
||||
+ wait_subprocess (child, "git", true, false, true, false, NULL);
|
||||
+ if (exitstatus == 0)
|
||||
+ {
|
||||
+ char *endptr;
|
||||
+ unsigned long git_log_time;
|
||||
+ if (xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK
|
||||
+ && endptr == line + strlen (line))
|
||||
+ {
|
||||
+ mtime->tv_sec = git_log_time;
|
||||
+ mtime->tv_nsec = 0;
|
||||
+ free (line);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ free (line);
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+vc_mtime (struct timespec *mtime, const char *filename)
|
||||
+{
|
||||
+ static bool git_tested;
|
||||
+ static bool git_present;
|
||||
+
|
||||
+ if (!git_tested)
|
||||
+ {
|
||||
+ /* Test for presence of git:
|
||||
+ "git --version >/dev/null 2>/dev/null" */
|
||||
+ const char *argv[3];
|
||||
+ int exitstatus;
|
||||
+
|
||||
+ argv[0] = "git";
|
||||
+ argv[1] = "--version";
|
||||
+ argv[2] = NULL;
|
||||
+ exitstatus = execute ("git", "git", argv, NULL, NULL,
|
||||
+ false, false, true, true,
|
||||
+ true, false, NULL);
|
||||
+ git_present = (exitstatus == 0);
|
||||
+ git_tested = true;
|
||||
+ }
|
||||
+
|
||||
+ if (git_present
|
||||
+ && git_vc_controlled (filename)
|
||||
+ && git_unmodified (filename))
|
||||
+ {
|
||||
+ if (git_mtime (mtime, filename) == 0)
|
||||
+ return 0;
|
||||
+ }
|
||||
+ struct stat statbuf;
|
||||
+ if (stat (filename, &statbuf) == 0)
|
||||
+ {
|
||||
+ *mtime = get_stat_mtime (&statbuf);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return -1;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/lib/vc-mtime.h
|
||||
@@ -0,0 +1,97 @@
|
||||
+/* Return the version-control based modification time of a file.
|
||||
+ Copyright (C) 2025 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 Bruno Haible <bruno@clisp.org>, 2025. */
|
||||
+
|
||||
+#ifndef _VC_MTIME_H
|
||||
+#define _VC_MTIME_H
|
||||
+
|
||||
+/* Get struct timespec. */
|
||||
+#include <time.h>
|
||||
+
|
||||
+/* The "version-controlled modification time" vc_mtime(F) of a file F
|
||||
+ is defined as:
|
||||
+ - If F is under version control and not modified locally:
|
||||
+ the time of the last change of F in the version control system.
|
||||
+ - Otherwise: The modification time of F on disk.
|
||||
+
|
||||
+ For now, the only VCS supported by this module is git. (hg and svn are
|
||||
+ hardly in use any more.)
|
||||
+
|
||||
+ This has the properties that:
|
||||
+ - Different users who have checked out the same git repo on different
|
||||
+ machines, at different times, and not done local modifications,
|
||||
+ get the same vc_mtime(F).
|
||||
+ - If a user has modified F locally, the modification time of that file
|
||||
+ counts.
|
||||
+ - If that user then reverts the modification, they then again get the
|
||||
+ same vc_mtime(F) as everyone else.
|
||||
+ - Different users who have unpacked the same tarball (without .git
|
||||
+ directory) on different machines, at different times, also get the same
|
||||
+ vc_mtime(F) [but possibly a different one than when the .git directory
|
||||
+ was present]. (Assuming a POSIX compliant file system.)
|
||||
+ - When a user commits local modifications into git, this only increases
|
||||
+ (not decreases) the vc_mtime(F).
|
||||
+
|
||||
+ The purpose of the version-controlled modification time is to produce a
|
||||
+ reproducible timestamp(Z) of a file Z that depends on files X1, ..., Xn,
|
||||
+ in such a way that
|
||||
+ - timestamp(Z) is reproducible, that is, different users on different
|
||||
+ machines get the same value.
|
||||
+ - timestamp(Z) is related to reality. It's not just a dummy, like what
|
||||
+ is suggested in <https://reproducible-builds.org/docs/timestamps/>.
|
||||
+ - One can arrange for timestamp(Z) to respect the modification time
|
||||
+ relations of a build system.
|
||||
+
|
||||
+ There are two uses of such a timestamp:
|
||||
+ - It can be set as the modification time of file Z in a file system, or
|
||||
+ - It can be embedded in Z, with the purpose of telling a user how old
|
||||
+ the file Z is. For example, in PDF files or in generated documentation,
|
||||
+ such a time is embedded in a special place.
|
||||
+
|
||||
+ The simplest example is a file Z that depends on files X1, ..., Xn.
|
||||
+ Generally one will define
|
||||
+ timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn))
|
||||
+ for an embedded timestamp, or
|
||||
+ timestamp(Z) = max (vc_mtime(X1), ..., vc_mtime(Xn)) + 1 second
|
||||
+ for a time stamp in a file system. The added second
|
||||
+ 1. accounts for fractional seconds in mtime(X1), ..., mtime(Xn),
|
||||
+ 2. allows for 'make' implementation that attempt to rebuild Z
|
||||
+ if mtime(Z) == mtime(Xi).
|
||||
+
|
||||
+ A more complicated example is when there are intermediate built files, not
|
||||
+ under version control. For example, if the build process produces
|
||||
+ X1, X2 -> Y1
|
||||
+ X3, X4 -> Y2
|
||||
+ Y1, Y2, X5 -> Z
|
||||
+ where Y1 and Y2 are intermediate built files, you should ignore the
|
||||
+ mtime(Y1), mtime(Y2), and consider only the vc_mtime(X1), ..., vc_mtime(X5).
|
||||
+ */
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+/* Determines the version-controlled modification time of FILENAME, stores it
|
||||
+ in *MTIME, and returns 0.
|
||||
+ Upon failure, it returns -1. */
|
||||
+extern int vc_mtime (struct timespec *mtime, const char *filename);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif /* _VC_MTIME_H */
|
||||
--- /dev/null
|
||||
+++ b/modules/vc-mtime
|
||||
@@ -0,0 +1,34 @@
|
||||
+Description:
|
||||
+Returns the version-control based modification time of a file.
|
||||
+
|
||||
+Files:
|
||||
+lib/vc-mtime.h
|
||||
+lib/vc-mtime.c
|
||||
+
|
||||
+Depends-on:
|
||||
+time-h
|
||||
+bool
|
||||
+spawn-pipe
|
||||
+wait-process
|
||||
+execute
|
||||
+safe-read
|
||||
+error
|
||||
+getline
|
||||
+xstrtol
|
||||
+stat-time
|
||||
+gettext-h
|
||||
+gnulib-i18n
|
||||
+
|
||||
+configure.ac:
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += vc-mtime.c
|
||||
+
|
||||
+Include:
|
||||
+"vm-mtime.h"
|
||||
+
|
||||
+License:
|
||||
+GPL
|
||||
+
|
||||
+Maintainer:
|
||||
+Bruno Haible
|
64
tools/gnulib/patches/755-clean-temp-hashkey.patch
Normal file
64
tools/gnulib/patches/755-clean-temp-hashkey.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From f47c5f2e21d0ccedb271b406e35b6963b23a64c4 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Wed, 30 Apr 2025 13:11:01 +0200
|
||||
Subject: [PATCH] clean-temp: Fix link error (regression yesterday).
|
||||
|
||||
* lib/clean-temp.c: Include hashkey-string.h.
|
||||
(create_temp_dir): Use hashkey_string_* functions instead of
|
||||
clean_temp_string_*.
|
||||
* lib/clean-temp-private.h (clean_temp_string_equals,
|
||||
clean_temp_string_hash): Remove declarations.
|
||||
* modules/clean-temp (Depends-on): Add hashkey-string.
|
||||
---
|
||||
ChangeLog | 10 ++++++++++
|
||||
lib/clean-temp-private.h | 3 ---
|
||||
lib/clean-temp.c | 5 +++--
|
||||
modules/clean-temp | 1 +
|
||||
4 files changed, 14 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/lib/clean-temp-private.h
|
||||
+++ b/lib/clean-temp-private.h
|
||||
@@ -68,9 +68,6 @@ struct closeable_fd
|
||||
#define descriptors clean_temp_descriptors
|
||||
extern gl_list_t /* <closeable_fd *> */ volatile descriptors;
|
||||
|
||||
-extern bool clean_temp_string_equals (const void *x1, const void *x2);
|
||||
-extern size_t clean_temp_string_hash (const void *x);
|
||||
-
|
||||
extern _GL_ASYNC_SAFE int clean_temp_asyncsafe_close (struct closeable_fd *element);
|
||||
extern void clean_temp_init_asyncsafe_close (void);
|
||||
|
||||
--- a/lib/clean-temp.c
|
||||
+++ b/lib/clean-temp.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "xmalloca.h"
|
||||
#include "glthread/lock.h"
|
||||
#include "thread-optim.h"
|
||||
+#include "hashkey-string.h"
|
||||
#include "gl_xlist.h"
|
||||
#include "gl_linkedhash_list.h"
|
||||
#include "gl_linked_list.h"
|
||||
@@ -221,11 +222,11 @@ create_temp_dir (const char *prefix, con
|
||||
tmpdir->cleanup_verbose = cleanup_verbose;
|
||||
tmpdir->subdirs =
|
||||
gl_list_create_empty (GL_LINKEDHASH_LIST,
|
||||
- clean_temp_string_equals, clean_temp_string_hash,
|
||||
+ hashkey_string_equals, hashkey_string_hash,
|
||||
NULL, false);
|
||||
tmpdir->files =
|
||||
gl_list_create_empty (GL_LINKEDHASH_LIST,
|
||||
- clean_temp_string_equals, clean_temp_string_hash,
|
||||
+ hashkey_string_equals, hashkey_string_hash,
|
||||
NULL, false);
|
||||
|
||||
/* Create the temporary directory. */
|
||||
--- a/modules/clean-temp
|
||||
+++ b/modules/clean-temp
|
||||
@@ -24,6 +24,7 @@ rmdir
|
||||
xalloc
|
||||
xalloc-die
|
||||
xmalloca
|
||||
+hashkey-string
|
||||
linkedhash-list
|
||||
linked-list
|
||||
xlist
|
1137
tools/gnulib/patches/795-string-desc-rename-functions.patch
Normal file
1137
tools/gnulib/patches/795-string-desc-rename-functions.patch
Normal file
File diff suppressed because it is too large
Load Diff
44
tools/gnulib/patches/796-vc-mtime-less-read.patch
Normal file
44
tools/gnulib/patches/796-vc-mtime-less-read.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 60cd34886c2c9f509974239fcf64a61f9a507d14 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Tue, 25 Feb 2025 09:04:28 +0100
|
||||
Subject: [PATCH] vc-mtime: Reduce number of read() system calls.
|
||||
|
||||
* lib/vc-mtime.c: Include <stddef.h>.
|
||||
(git_vc_controlled): Read bytes into a buffer, not one-by-one.
|
||||
---
|
||||
ChangeLog | 6 ++++++
|
||||
lib/vc-mtime.c | 15 +++++++++++----
|
||||
2 files changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/lib/vc-mtime.c
|
||||
+++ b/lib/vc-mtime.c
|
||||
@@ -21,6 +21,7 @@
|
||||
/* Specification. */
|
||||
#include "vc-mtime.h"
|
||||
|
||||
+#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -56,11 +57,17 @@ git_vc_controlled (const char *filename)
|
||||
return false;
|
||||
|
||||
/* Read the subprocess output, and test whether it is non-empty. */
|
||||
- size_t count = 0;
|
||||
- char c;
|
||||
+ ptrdiff_t count = 0;
|
||||
|
||||
- while (safe_read (fd[0], &c, 1) > 0)
|
||||
- count++;
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ char buf[1024];
|
||||
+ ptrdiff_t n = safe_read (fd[0], buf, sizeof (buf));
|
||||
+ if (n > 0)
|
||||
+ count += n;
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
close (fd[0]);
|
||||
|
968
tools/gnulib/patches/797-vc-mtime-add-api.patch
Normal file
968
tools/gnulib/patches/797-vc-mtime-add-api.patch
Normal file
@ -0,0 +1,968 @@
|
||||
From 78269749030dde23182c29376d1410592436eb5d Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Thu, 1 May 2025 17:26:27 +0200
|
||||
Subject: [PATCH] vc-mtime: Add API for more efficient use of git.
|
||||
|
||||
Reported by Serhii Tereshchenko, Arthur, Adam YS, Foucauld Degeorges
|
||||
at <https://savannah.gnu.org/bugs/?66865>.
|
||||
|
||||
* lib/vc-mtime.h (max_vc_mtime): New declaration.
|
||||
* lib/vc-mtime.c: Include <errno.h>, <stdio.h>, <string.h>, filename.h,
|
||||
xalloc.h, xgetcwd.h, xvasprintf.h, gl_map.h, gl_xmap.h, gl_hash_map.h,
|
||||
hashkey-string.h, unlocked-io.h.
|
||||
(is_git_present): New function, extracted from vc_mtime.
|
||||
(vc_mtime): Invoke it.
|
||||
(MAX_COMMAND_LENGTH, MAX_CMD_LEN): New macros.
|
||||
(abs_git_checkout): New function, based on execute_and_read_line in
|
||||
lib/javacomp.c.
|
||||
(ancestor_level, relativize): New functions.
|
||||
(struct accumulator): New type.
|
||||
(accumulate): New function.
|
||||
(max_vc_mtime): New function.
|
||||
(test_ancestor_level, test_relativize, main) [TEST]: New functions.
|
||||
* modules/vc-mtime (Depends-on): Add filename, xalloc, xgetcwd,
|
||||
canonicalize-lgpl, xvasprintf, str_startswith, map, xmap, hash-map,
|
||||
hashkey-string, getdelim.
|
||||
---
|
||||
ChangeLog | 23 ++
|
||||
lib/vc-mtime.c | 866 +++++++++++++++++++++++++++++++++++++++++++++--
|
||||
lib/vc-mtime.h | 7 +
|
||||
modules/vc-mtime | 11 +
|
||||
4 files changed, 886 insertions(+), 21 deletions(-)
|
||||
|
||||
--- a/lib/vc-mtime.c
|
||||
+++ b/lib/vc-mtime.c
|
||||
@@ -21,8 +21,11 @@
|
||||
/* Specification. */
|
||||
#include "vc-mtime.h"
|
||||
|
||||
+#include <errno.h>
|
||||
#include <stddef.h>
|
||||
+#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <error.h>
|
||||
@@ -32,11 +35,51 @@
|
||||
#include "safe-read.h"
|
||||
#include "xstrtol.h"
|
||||
#include "stat-time.h"
|
||||
+#include "filename.h"
|
||||
+#include "xalloc.h"
|
||||
+#include "xgetcwd.h"
|
||||
+#include "xvasprintf.h"
|
||||
+#include "gl_map.h"
|
||||
+#include "gl_xmap.h"
|
||||
+#include "gl_hash_map.h"
|
||||
+#include "hashkey-string.h"
|
||||
+#if USE_UNLOCKED_IO
|
||||
+# include "unlocked-io.h"
|
||||
+#endif
|
||||
#include "gettext.h"
|
||||
|
||||
#define _(msgid) dgettext ("gnulib", msgid)
|
||||
|
||||
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
+/* Determines whether git is present. */
|
||||
+static bool
|
||||
+is_git_present (void)
|
||||
+{
|
||||
+ static bool git_tested;
|
||||
+ static bool git_present;
|
||||
+
|
||||
+ if (!git_tested)
|
||||
+ {
|
||||
+ /* Test for presence of git:
|
||||
+ "git --version >/dev/null 2>/dev/null" */
|
||||
+ const char *argv[3];
|
||||
+ int exitstatus;
|
||||
+
|
||||
+ argv[0] = "git";
|
||||
+ argv[1] = "--version";
|
||||
+ argv[2] = NULL;
|
||||
+ exitstatus = execute ("git", "git", argv, NULL, NULL,
|
||||
+ false, false, true, true,
|
||||
+ true, false, NULL);
|
||||
+ git_present = (exitstatus == 0);
|
||||
+ git_tested = true;
|
||||
+ }
|
||||
+
|
||||
+ return git_present;
|
||||
+}
|
||||
+
|
||||
/* Determines whether the specified file is under version control. */
|
||||
static bool
|
||||
git_vc_controlled (const char *filename)
|
||||
@@ -178,27 +221,7 @@ git_mtime (struct timespec *mtime, const
|
||||
int
|
||||
vc_mtime (struct timespec *mtime, const char *filename)
|
||||
{
|
||||
- static bool git_tested;
|
||||
- static bool git_present;
|
||||
-
|
||||
- if (!git_tested)
|
||||
- {
|
||||
- /* Test for presence of git:
|
||||
- "git --version >/dev/null 2>/dev/null" */
|
||||
- const char *argv[3];
|
||||
- int exitstatus;
|
||||
-
|
||||
- argv[0] = "git";
|
||||
- argv[1] = "--version";
|
||||
- argv[2] = NULL;
|
||||
- exitstatus = execute ("git", "git", argv, NULL, NULL,
|
||||
- false, false, true, true,
|
||||
- true, false, NULL);
|
||||
- git_present = (exitstatus == 0);
|
||||
- git_tested = true;
|
||||
- }
|
||||
-
|
||||
- if (git_present
|
||||
+ if (is_git_present ()
|
||||
&& git_vc_controlled (filename)
|
||||
&& git_unmodified (filename))
|
||||
{
|
||||
@@ -213,3 +236,804 @@ vc_mtime (struct timespec *mtime, const
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
+
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
+/* Maximum length of a command that is guaranteed to work. */
|
||||
+#if defined _WIN32 || defined __CYGWIN__
|
||||
+/* Windows */
|
||||
+# define MAX_COMMAND_LENGTH 8192
|
||||
+#else
|
||||
+/* Unix platforms */
|
||||
+# define MAX_COMMAND_LENGTH 32768
|
||||
+#endif
|
||||
+/* Keep some safe distance to this maximum. */
|
||||
+#define MAX_CMD_LEN ((int) (MAX_COMMAND_LENGTH * 0.8))
|
||||
+
|
||||
+/* Returns the directory name of the git checkout that contains tha current
|
||||
+ directory, as an absolute file name, or NULL if the current directory is
|
||||
+ not in a git checkout. */
|
||||
+static char *
|
||||
+abs_git_checkout (void)
|
||||
+{
|
||||
+ /* Run "git rev-parse --show-toplevel 2>/dev/null" and return its output,
|
||||
+ without the trailing newline. */
|
||||
+ const char *argv[4];
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
+
|
||||
+ argv[0] = "git";
|
||||
+ argv[1] = "rev-parse";
|
||||
+ argv[2] = "--show-toplevel";
|
||||
+ argv[3] = NULL;
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+
|
||||
+ if (child == -1)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* Retrieve its result. */
|
||||
+ FILE *fp = fdopen (fd[0], "r");
|
||||
+ if (fp == NULL)
|
||||
+ error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
+
|
||||
+ char *line = NULL;
|
||||
+ size_t linesize = 0;
|
||||
+ size_t linelen = getline (&line, &linesize, fp);
|
||||
+ if (linelen == (size_t)(-1))
|
||||
+ {
|
||||
+ fclose (fp);
|
||||
+ wait_subprocess (child, "git", true, true, true, false, NULL);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ int exitstatus;
|
||||
+
|
||||
+ if (linelen > 0 && line[linelen - 1] == '\n')
|
||||
+ line[linelen - 1] = '\0';
|
||||
+
|
||||
+ /* Read until EOF (otherwise the child process may get a SIGPIPE signal). */
|
||||
+ while (getc (fp) != EOF)
|
||||
+ ;
|
||||
+
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit status. */
|
||||
+ exitstatus =
|
||||
+ wait_subprocess (child, "git", true, true, true, false, NULL);
|
||||
+ if (exitstatus == 0)
|
||||
+ return line;
|
||||
+ }
|
||||
+ free (line);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+/* Given an absolute canonicalized directory DIR1 and an absolute canonicalized
|
||||
+ directory DIR2, returns N where DIR1 = DIR2 "/.." ... "/.." with N times
|
||||
+ "/..", or -1 if DIR1 is not an ancestor directory of DIR2. */
|
||||
+static long
|
||||
+ancestor_level (const char *dir1, const char *dir2)
|
||||
+{
|
||||
+ if (strcmp (dir1, "/") == 0)
|
||||
+ dir1 = "";
|
||||
+ if (strcmp (dir2, "/") == 0)
|
||||
+ dir2 = "";
|
||||
+ size_t dir1_len = strlen (dir1);
|
||||
+ if (strncmp (dir1, dir2, dir1_len) == 0)
|
||||
+ {
|
||||
+ /* DIR2 starts with DIR1. */
|
||||
+ const char *p = dir2 + dir1_len;
|
||||
+ if (*p == '\0')
|
||||
+ /* DIR2 and DIR1 are the same. */
|
||||
+ return 0;
|
||||
+ if (ISSLASH (*p))
|
||||
+ {
|
||||
+ /* Return the number of slashes in the tail of DIR2 that starts
|
||||
+ at P. */
|
||||
+ long n = 1;
|
||||
+ p++;
|
||||
+ for (; *p != '\0'; p++)
|
||||
+ if (ISSLASH (*p))
|
||||
+ n++;
|
||||
+ return n;
|
||||
+ }
|
||||
+ }
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/* Given an absolute canolicalized FILENAME that starts with DIR1, returns the
|
||||
+ same file name relative to DIR2, where DIR1 = DIR2 "/.." ... "/.." with
|
||||
+ N times "/..", as a freshly allocated string. */
|
||||
+static char *
|
||||
+relativize (const char *filename,
|
||||
+ unsigned long n, const char *dir1, const char *dir2)
|
||||
+{
|
||||
+ if (strcmp (dir1, "/") == 0)
|
||||
+ dir1 = "";
|
||||
+ size_t dir1_len = strlen (dir1);
|
||||
+ if (!(strncmp (filename, dir1, dir1_len) == 0
|
||||
+ && (filename[dir1_len] == '\0' || ISSLASH (filename[dir1_len]))))
|
||||
+ /* Invalid argument. */
|
||||
+ abort ();
|
||||
+ if (strcmp (dir2, "/") == 0)
|
||||
+ dir2 = "";
|
||||
+
|
||||
+ dir2 += dir1_len;
|
||||
+ filename += dir1_len;
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ /* Invariant: The result will be N times "../" followed by FILENAME. */
|
||||
+ if (*filename == '\0')
|
||||
+ break;
|
||||
+ if (!ISSLASH (*filename))
|
||||
+ abort ();
|
||||
+ filename++;
|
||||
+ if (*dir2 == '\0')
|
||||
+ break;
|
||||
+ if (!ISSLASH (*dir2))
|
||||
+ abort ();
|
||||
+ dir2++;
|
||||
+ /* Skip one component in DIR2. */
|
||||
+ const char *dir2_s;
|
||||
+ for (dir2_s = dir2; *dir2_s != '\0'; dir2_s++)
|
||||
+ if (ISSLASH (*dir2_s))
|
||||
+ break;
|
||||
+ /* Skip one component in FILENAME, at P. */
|
||||
+ const char *filename_s;
|
||||
+ for (filename_s = filename; *filename_s != '\0'; filename_s++)
|
||||
+ if (ISSLASH (*filename_s))
|
||||
+ break;
|
||||
+ /* Did the components match? */
|
||||
+ if (!(filename_s - filename == dir2_s - dir2
|
||||
+ && memcmp (filename, dir2, dir2_s - dir2) == 0))
|
||||
+ break;
|
||||
+ dir2 = dir2_s;
|
||||
+ filename = filename_s;
|
||||
+ n--;
|
||||
+ }
|
||||
+
|
||||
+ if (n == 0 && *filename == '\0')
|
||||
+ return xstrdup (".");
|
||||
+
|
||||
+ char *result = (char *) xmalloc (3 * n + strlen (filename) + 1);
|
||||
+ {
|
||||
+ char *q = result;
|
||||
+ for (; n > 0; n--)
|
||||
+ {
|
||||
+ q[0] = '.'; q[1] = '.'; q[2] = '/'; q += 3;
|
||||
+ }
|
||||
+ strcpy (q, filename);
|
||||
+ }
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/* Accumulating mtimes. */
|
||||
+struct accumulator
|
||||
+{
|
||||
+ bool has_some_mtimes;
|
||||
+ struct timespec max_of_mtimes;
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+accumulate (struct accumulator *accu, struct timespec mtime)
|
||||
+{
|
||||
+ if (accu->has_some_mtimes)
|
||||
+ {
|
||||
+ /* Compute the maximum of accu->max_of_mtimes and mtime. */
|
||||
+ if (accu->max_of_mtimes.tv_sec < mtime.tv_sec
|
||||
+ || (accu->max_of_mtimes.tv_sec == mtime.tv_sec
|
||||
+ && accu->max_of_mtimes.tv_nsec < mtime.tv_nsec))
|
||||
+ accu->max_of_mtimes = mtime;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ accu->max_of_mtimes = mtime;
|
||||
+ accu->has_some_mtimes = true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+max_vc_mtime (struct timespec *max_of_mtimes,
|
||||
+ size_t nfiles, const char * const *filenames)
|
||||
+{
|
||||
+ if (nfiles == 0)
|
||||
+ /* Invalid argument. */
|
||||
+ abort ();
|
||||
+
|
||||
+ struct accumulator accu = { false };
|
||||
+
|
||||
+ /* Determine which of the specified files are under version control,
|
||||
+ and which are duplicates. (The case of duplicates is rare, but it needs
|
||||
+ special attention, because 'git ls-files' eliminates duplicates.)
|
||||
+ vc_controlled[n] = 1 means that filenames[n] is under version control.
|
||||
+ vc_controlled[n] = 0 means that filenames[n] is not under version control.
|
||||
+ vc_controlled[n] = -1 means that filenames[n] is a duplicate. */
|
||||
+ signed char *vc_controlled = XNMALLOC (nfiles, signed char);
|
||||
+ for (size_t n = 0; n < nfiles; n++)
|
||||
+ vc_controlled[n] = 0;
|
||||
+
|
||||
+ if (is_git_present ())
|
||||
+ {
|
||||
+ /* Since 'git ls-files' produces an error when at least one of the files
|
||||
+ is outside the git checkout that contains tha current directory, we
|
||||
+ need to filter out such files. This is most easily done by converting
|
||||
+ each file name to a canonical file name first and then comparing with
|
||||
+ the directory name of said git checkout. */
|
||||
+ char *git_checkout = abs_git_checkout ();
|
||||
+ if (git_checkout != NULL)
|
||||
+ {
|
||||
+ char *currdir = xgetcwd ();
|
||||
+ /* git_checkout is expected to be an ancestor directory of the
|
||||
+ current directory. */
|
||||
+ long ancestor = ancestor_level (git_checkout, currdir);
|
||||
+ if (ancestor >= 0)
|
||||
+ {
|
||||
+ char **canonical_filenames = XNMALLOC (nfiles, char *);
|
||||
+ for (size_t n = 0; n < nfiles; n++)
|
||||
+ {
|
||||
+ char *canonical = canonicalize_file_name (filenames[n]);
|
||||
+ if (canonical == NULL)
|
||||
+ {
|
||||
+ if (errno == ENOMEM)
|
||||
+ xalloc_die ();
|
||||
+ /* The file filenames[n] does not exist. */
|
||||
+ for (size_t k = n; k > 0; )
|
||||
+ free (canonical_filenames[--k]);
|
||||
+ free (canonical_filenames);
|
||||
+ free (currdir);
|
||||
+ free (git_checkout);
|
||||
+ free (vc_controlled);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ canonical_filenames[n] = canonical;
|
||||
+ }
|
||||
+
|
||||
+ /* Test which of these absolute file names are outside of the
|
||||
+ git_checkout. */
|
||||
+ char *git_checkout_slash =
|
||||
+ (strcmp (git_checkout, "/") == 0
|
||||
+ ? xstrdup (git_checkout)
|
||||
+ : xasprintf ("%s/", git_checkout));
|
||||
+
|
||||
+ char **checkout_relative_filenames = XNMALLOC (nfiles, char *);
|
||||
+ char **currdir_relative_filenames = XNMALLOC (nfiles, char *);
|
||||
+ for (size_t n = 0; n < nfiles; n++)
|
||||
+ {
|
||||
+ if (str_startswith (canonical_filenames[n], git_checkout_slash))
|
||||
+ {
|
||||
+ vc_controlled[n] = 1;
|
||||
+ checkout_relative_filenames[n] =
|
||||
+ relativize (canonical_filenames[n],
|
||||
+ 0, git_checkout, git_checkout);
|
||||
+ currdir_relative_filenames[n] =
|
||||
+ relativize (canonical_filenames[n],
|
||||
+ ancestor, git_checkout, currdir);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ vc_controlled[n] = 0;
|
||||
+ checkout_relative_filenames[n] = NULL;
|
||||
+ currdir_relative_filenames[n] = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Room for passing arguments to git commands. */
|
||||
+ const char **argv = XNMALLOC (6 + nfiles + 1, const char *);
|
||||
+
|
||||
+ {
|
||||
+ /* Put the relative file names into a hash table. This is needed
|
||||
+ because 'git ls-files' returns the files in a different order
|
||||
+ than the one we provide in the command. */
|
||||
+ gl_map_t relative_filenames_ht =
|
||||
+ gl_map_create_empty (GL_HASH_MAP,
|
||||
+ hashkey_string_equals, hashkey_string_hash,
|
||||
+ NULL, NULL);
|
||||
+ for (size_t n = 0; n < nfiles; n++)
|
||||
+ if (currdir_relative_filenames[n] != NULL)
|
||||
+ {
|
||||
+ if (gl_map_get (relative_filenames_ht, currdir_relative_filenames[n]) != NULL)
|
||||
+ {
|
||||
+ /* It's already in the table. */
|
||||
+ vc_controlled[n] = -1;
|
||||
+ }
|
||||
+ else
|
||||
+ gl_map_put (relative_filenames_ht, currdir_relative_filenames[n], &vc_controlled[n]);
|
||||
+ }
|
||||
+
|
||||
+ /* Run "git ls-files -c -o -t -z FILE1..." for as many files as
|
||||
+ possible, and inspect the output. */
|
||||
+ size_t n0 = 0;
|
||||
+ do
|
||||
+ {
|
||||
+ size_t i = 0;
|
||||
+ argv[i++] = "git";
|
||||
+ argv[i++] = "ls-files";
|
||||
+ argv[i++] = "-c";
|
||||
+ argv[i++] = "-o";
|
||||
+ argv[i++] = "-t";
|
||||
+ argv[i++] = "-z";
|
||||
+ size_t i0 = i;
|
||||
+
|
||||
+ size_t n = n0;
|
||||
+ size_t cmd_len = 25;
|
||||
+ for (; n < nfiles; n++)
|
||||
+ {
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
+ && i > i0)
|
||||
+ break;
|
||||
+ argv[i++] = currdir_relative_filenames[n];
|
||||
+ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
+ }
|
||||
+ n++;
|
||||
+ }
|
||||
+ if (i > i0)
|
||||
+ {
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
+
|
||||
+ argv[i] = NULL;
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+ if (child == -1)
|
||||
+ break;
|
||||
+
|
||||
+ /* Read the subprocess output. It is expected to be of the form
|
||||
+ T1 <space> <currdir_relative_filename1> NUL
|
||||
+ T2 <space> <currdir_relative_filename2> NUL
|
||||
+ ...
|
||||
+ where the relative filenames correspond to the given file
|
||||
+ names (because we have already relativized them). */
|
||||
+ FILE *fp = fdopen (fd[0], "r");
|
||||
+ if (fp == NULL)
|
||||
+ error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
+
|
||||
+ char *fn = NULL;
|
||||
+ size_t fn_size = 0;
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ int status = fgetc (fp);
|
||||
+ if (status == EOF)
|
||||
+ break;
|
||||
+ /* status is a status tag, as documented in
|
||||
+ "man git-ls-files". */
|
||||
+
|
||||
+ int space = fgetc (fp);
|
||||
+ if (space != ' ')
|
||||
+ {
|
||||
+ fprintf (stderr, "vc-mtime: git ls-files output not as expected\n");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (getdelim (&fn, &fn_size, '\0', fp) == -1)
|
||||
+ {
|
||||
+ if (errno == ENOMEM)
|
||||
+ xalloc_die ();
|
||||
+ fprintf (stderr, "vc-mtime: failed to read git ls-files output\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ signed char *vc_controlled_p =
|
||||
+ (signed char *) gl_map_get (relative_filenames_ht, fn);
|
||||
+ if (vc_controlled_p == NULL)
|
||||
+ fprintf (stderr, "vc-mtime: git ls-files returned an unexpected file name: %s\n", fn);
|
||||
+ else
|
||||
+ *vc_controlled_p = (status == 'H' ? 1 : 0);
|
||||
+ }
|
||||
+
|
||||
+ free (fn);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit status. */
|
||||
+ int exitstatus =
|
||||
+ wait_subprocess (child, "git", false, true, true, false, NULL);
|
||||
+ if (exitstatus != 0)
|
||||
+ fprintf (stderr, "vc-mtime: git ls-files failed with exit code %d\n", exitstatus);
|
||||
+ }
|
||||
+ n0 = n;
|
||||
+ }
|
||||
+ while (n0 < nfiles);
|
||||
+
|
||||
+ gl_map_free (relative_filenames_ht);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ /* Put the relative file names into a hash table. This is needed
|
||||
+ because 'git diff' returns the files in a different order
|
||||
+ than the one we provide in the command. */
|
||||
+ gl_map_t relative_filenames_ht =
|
||||
+ gl_map_create_empty (GL_HASH_MAP,
|
||||
+ hashkey_string_equals, hashkey_string_hash,
|
||||
+ NULL, NULL);
|
||||
+ for (size_t n = 0; n < nfiles; n++)
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ /* No need to test for duplicates here. We have already set
|
||||
+ vc_controlled[n] to -1 for duplicates, above. */
|
||||
+ gl_map_put (relative_filenames_ht, checkout_relative_filenames[n], &vc_controlled[n]);
|
||||
+ }
|
||||
+
|
||||
+ /* Run "git diff --name-only --no-relative -z HEAD -- FILE1..." for
|
||||
+ as many files as possible, and inspect the output. */
|
||||
+ size_t n0 = 0;
|
||||
+ do
|
||||
+ {
|
||||
+ size_t i = 0;
|
||||
+ argv[i++] = "git";
|
||||
+ argv[i++] = "diff";
|
||||
+ argv[i++] = "--name-only";
|
||||
+ argv[i++] = "--no-relative";
|
||||
+ argv[i++] = "-z";
|
||||
+ argv[i++] = "HEAD";
|
||||
+ argv[i++] = "--";
|
||||
+ size_t i0 = i;
|
||||
+
|
||||
+ size_t n = n0;
|
||||
+ size_t cmd_len = 46;
|
||||
+ for (; n < nfiles; n++)
|
||||
+ {
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
+ && i > i0)
|
||||
+ break;
|
||||
+ argv[i++] = currdir_relative_filenames[n];
|
||||
+ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
+ }
|
||||
+ n++;
|
||||
+ }
|
||||
+ if (i > i0)
|
||||
+ {
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
+
|
||||
+ argv[i] = NULL;
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+ if (child == -1)
|
||||
+ break;
|
||||
+
|
||||
+ /* Read the subprocess output. It is expected to be of the form
|
||||
+ <checkout_relative_filename1> NUL
|
||||
+ <checkout_relative_filename2> NUL
|
||||
+ ...
|
||||
+ where the relative filenames are relative to the git
|
||||
+ checkout dir, not to currdir! */
|
||||
+ FILE *fp = fdopen (fd[0], "r");
|
||||
+ if (fp == NULL)
|
||||
+ error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
+
|
||||
+ char *fn = NULL;
|
||||
+ size_t fn_size = 0;
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ /* Test for EOF. */
|
||||
+ int c = fgetc (fp);
|
||||
+ if (c == EOF)
|
||||
+ break;
|
||||
+ ungetc (c, fp);
|
||||
+
|
||||
+ if (getdelim (&fn, &fn_size, '\0', fp) == -1)
|
||||
+ {
|
||||
+ if (errno == ENOMEM)
|
||||
+ xalloc_die ();
|
||||
+ fprintf (stderr, "vc-mtime: failed to read git diff output\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ signed char *vc_controlled_p =
|
||||
+ (signed char *) gl_map_get (relative_filenames_ht, fn);
|
||||
+ if (vc_controlled_p == NULL)
|
||||
+ fprintf (stderr, "vc-mtime: git diff returned an unexpected file name: %s\n", fn);
|
||||
+ else
|
||||
+ /* filenames[n] is under version control but is modified.
|
||||
+ Treat it like a file not under version control. */
|
||||
+ *vc_controlled_p = 0;
|
||||
+ }
|
||||
+
|
||||
+ free (fn);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit status. */
|
||||
+ int exitstatus =
|
||||
+ wait_subprocess (child, "git", false, true, true, false, NULL);
|
||||
+ if (exitstatus != 0)
|
||||
+ fprintf (stderr, "vc-mtime: git diff failed with exit code %d\n", exitstatus);
|
||||
+ }
|
||||
+ n0 = n;
|
||||
+ }
|
||||
+ while (n0 < nfiles);
|
||||
+
|
||||
+ gl_map_free (relative_filenames_ht);
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ /* Run "git log -1 --format=%ct -- FILE1...". It prints the
|
||||
+ time of last modification (the 'CommitDate', not the
|
||||
+ 'AuthorDate' which merely represents the time at which the
|
||||
+ author locally committed the first version of the change),
|
||||
+ as the number of seconds since the Epoch. The '--' option
|
||||
+ is for the case that the specified file was removed. */
|
||||
+ size_t n0 = 0;
|
||||
+ do
|
||||
+ {
|
||||
+ size_t i = 0;
|
||||
+ argv[i++] = "git";
|
||||
+ argv[i++] = "log";
|
||||
+ argv[i++] = "-1";
|
||||
+ argv[i++] = "--format=%ct";
|
||||
+ argv[i++] = "--";
|
||||
+ size_t i0 = i;
|
||||
+
|
||||
+ size_t n = n0;
|
||||
+ size_t cmd_len = 27;
|
||||
+ for (; n < nfiles; n++)
|
||||
+ {
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
+ && i > i0)
|
||||
+ break;
|
||||
+ argv[i++] = currdir_relative_filenames[n];
|
||||
+ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
+ }
|
||||
+ n++;
|
||||
+ }
|
||||
+ if (i > i0)
|
||||
+ {
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
+
|
||||
+ argv[i] = NULL;
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+ if (child == -1)
|
||||
+ break;
|
||||
+
|
||||
+ /* Read the subprocess output. It is expected to be a
|
||||
+ single line, containing a positive integer. */
|
||||
+ FILE *fp = fdopen (fd[0], "r");
|
||||
+ if (fp == NULL)
|
||||
+ error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
+
|
||||
+ char *line = NULL;
|
||||
+ size_t linesize = 0;
|
||||
+ size_t linelen = getline (&line, &linesize, fp);
|
||||
+ if (linelen == (size_t)(-1))
|
||||
+ {
|
||||
+ if (errno == ENOMEM)
|
||||
+ xalloc_die ();
|
||||
+ fprintf (stderr, "vc-mtime: failed to read git log output\n");
|
||||
+ git_log_fail1:
|
||||
+ free (line);
|
||||
+ fclose (fp);
|
||||
+ wait_subprocess (child, "git", true, false, true, false, NULL);
|
||||
+ git_log_fail2:
|
||||
+ free (argv);
|
||||
+ for (size_t k = nfiles; k > 0; )
|
||||
+ free (currdir_relative_filenames[--k]);
|
||||
+ free (currdir_relative_filenames);
|
||||
+ for (size_t k = nfiles; k > 0; )
|
||||
+ free (checkout_relative_filenames[--k]);
|
||||
+ free (checkout_relative_filenames);
|
||||
+ free (git_checkout_slash);
|
||||
+ for (size_t k = nfiles; k > 0; )
|
||||
+ free (canonical_filenames[--k]);
|
||||
+ free (canonical_filenames);
|
||||
+ free (currdir);
|
||||
+ free (git_checkout);
|
||||
+ free (vc_controlled);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (linelen > 0 && line[linelen - 1] == '\n')
|
||||
+ line[linelen - 1] = '\0';
|
||||
+
|
||||
+ char *endptr;
|
||||
+ unsigned long git_log_time;
|
||||
+ if (!(xstrtoul (line, &endptr, 10, &git_log_time, NULL) == LONGINT_OK
|
||||
+ && endptr == line + strlen (line)))
|
||||
+ {
|
||||
+ fprintf (stderr, "vc-mtime: git log output not as expected\n");
|
||||
+ goto git_log_fail1;
|
||||
+ }
|
||||
+
|
||||
+ struct timespec mtime;
|
||||
+ mtime.tv_sec = git_log_time;
|
||||
+ mtime.tv_nsec = 0;
|
||||
+ accumulate (&accu, mtime);
|
||||
+
|
||||
+ free (line);
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit status. */
|
||||
+ int exitstatus =
|
||||
+ wait_subprocess (child, "git", false, true, true, false, NULL);
|
||||
+ if (exitstatus != 0)
|
||||
+ {
|
||||
+ fprintf (stderr, "vc-mtime: git log failed with exit code %d\n", exitstatus);
|
||||
+ goto git_log_fail2;
|
||||
+ }
|
||||
+ }
|
||||
+ n0 = n;
|
||||
+ }
|
||||
+ while (n0 < nfiles);
|
||||
+ }
|
||||
+
|
||||
+ free (argv);
|
||||
+ for (size_t k = nfiles; k > 0; )
|
||||
+ free (currdir_relative_filenames[--k]);
|
||||
+ free (currdir_relative_filenames);
|
||||
+ for (size_t k = nfiles; k > 0; )
|
||||
+ free (checkout_relative_filenames[--k]);
|
||||
+ free (checkout_relative_filenames);
|
||||
+ free (git_checkout_slash);
|
||||
+ for (size_t k = nfiles; k > 0; )
|
||||
+ free (canonical_filenames[--k]);
|
||||
+ free (canonical_filenames);
|
||||
+ }
|
||||
+ free (currdir);
|
||||
+ }
|
||||
+ free (git_checkout);
|
||||
+ }
|
||||
+
|
||||
+ /* For the files that are not under version control, or that are modified
|
||||
+ compared to HEAD, use the file's time stamp. */
|
||||
+ for (size_t n = 0; n < nfiles; n++)
|
||||
+ if (vc_controlled[n] == 0)
|
||||
+ {
|
||||
+ struct stat statbuf;
|
||||
+ if (stat (filenames[n], &statbuf) < 0)
|
||||
+ {
|
||||
+ free (vc_controlled);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ struct timespec mtime = get_stat_mtime (&statbuf);
|
||||
+ accumulate (&accu, mtime);
|
||||
+ }
|
||||
+
|
||||
+ free (vc_controlled);
|
||||
+
|
||||
+ /* Since nfiles > 0, we must have accumulated at least one mtime. */
|
||||
+ if (!accu.has_some_mtimes)
|
||||
+ abort ();
|
||||
+ *max_of_mtimes = accu.max_of_mtimes;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* ========================================================================== */
|
||||
+
|
||||
+#ifdef TEST
|
||||
+
|
||||
+#include <assert.h>
|
||||
+#include <stdio.h>
|
||||
+#include <time.h>
|
||||
+
|
||||
+/* Some unit tests for internal functions. */
|
||||
+
|
||||
+static void
|
||||
+test_ancestor_level (void)
|
||||
+{
|
||||
+ assert (ancestor_level ("/home/user/projects/gnulib", "/home/user/projects/gnulib") == 0);
|
||||
+ assert (ancestor_level ("/", "/") == 0);
|
||||
+
|
||||
+ assert (ancestor_level ("/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto") == 2);
|
||||
+ assert (ancestor_level ("/", "/home/user") == 2);
|
||||
+
|
||||
+ assert (ancestor_level ("/home/user/.local", "/home/user/projects/gnulib") == -1);
|
||||
+ assert (ancestor_level ("/.local", "/home/user") == -1);
|
||||
+ assert (ancestor_level ("/.local", "/") == -1);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_relativize (void)
|
||||
+{
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib",
|
||||
+ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"),
|
||||
+ ".") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/NEWS",
|
||||
+ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"),
|
||||
+ "NEWS") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/doc/Makefile",
|
||||
+ 0, "/home/user/projects/gnulib", "/home/user/projects/gnulib"),
|
||||
+ "doc/Makefile") == 0);
|
||||
+
|
||||
+ assert (strcmp (relativize ("/",
|
||||
+ 0, "/", "/"),
|
||||
+ ".") == 0);
|
||||
+ assert (strcmp (relativize ("/swapfile",
|
||||
+ 0, "/", "/"),
|
||||
+ "swapfile") == 0);
|
||||
+ assert (strcmp (relativize ("/etc/passwd",
|
||||
+ 0, "/", "/"),
|
||||
+ "etc/passwd") == 0);
|
||||
+
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../../") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/crypto",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ ".") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/malloc",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../malloc") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/cr",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../cr") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/lib/cryptography",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../cryptography") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/doc",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../../doc") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user/projects/gnulib/doc/Makefile",
|
||||
+ 2, "/home/user/projects/gnulib", "/home/user/projects/gnulib/lib/crypto"),
|
||||
+ "../../doc/Makefile") == 0);
|
||||
+
|
||||
+ assert (strcmp (relativize ("/",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../../") == 0);
|
||||
+ assert (strcmp (relativize ("/home",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../") == 0);
|
||||
+ assert (strcmp (relativize ("/home/user",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ ".") == 0);
|
||||
+ assert (strcmp (relativize ("/home/root",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../root") == 0);
|
||||
+ assert (strcmp (relativize ("/home/us",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../us") == 0);
|
||||
+ assert (strcmp (relativize ("/home/users",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../users") == 0);
|
||||
+ assert (strcmp (relativize ("/etc",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../../etc") == 0);
|
||||
+ assert (strcmp (relativize ("/etc/passwd",
|
||||
+ 2, "/", "/home/user"),
|
||||
+ "../../etc/passwd") == 0);
|
||||
+}
|
||||
+
|
||||
+/* Usage: ./a.out FILE[...]
|
||||
+ */
|
||||
+int
|
||||
+main (int argc, char *argv[])
|
||||
+{
|
||||
+ test_ancestor_level ();
|
||||
+ test_relativize ();
|
||||
+
|
||||
+ if (argc == 1)
|
||||
+ {
|
||||
+ fprintf (stderr, "Usage: ./a.out FILE[...]\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ struct timespec mtime;
|
||||
+ int ret = max_vc_mtime (&mtime, argc - 1, (const char **) argv + 1);
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ time_t t = mtime.tv_sec;
|
||||
+ struct tm *gmt = gmtime (&t);
|
||||
+ printf ("mtime = %04d-%02d-%02d %02d:%02d:%02d UTC\n",
|
||||
+ gmt->tm_year + 1900, gmt->tm_mon + 1, gmt->tm_mday,
|
||||
+ gmt->tm_hour, gmt->tm_min, gmt->tm_sec);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ printf ("failed\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Local Variables:
|
||||
+ * compile-command: "gcc -ggdb -DTEST -Wall -I. -I.. vc-mtime.c libgnu.a"
|
||||
+ * End:
|
||||
+ */
|
||||
+
|
||||
+#endif
|
||||
--- a/lib/vc-mtime.h
|
||||
+++ b/lib/vc-mtime.h
|
||||
@@ -90,6 +90,13 @@ extern "C" {
|
||||
Upon failure, it returns -1. */
|
||||
extern int vc_mtime (struct timespec *mtime, const char *filename);
|
||||
|
||||
+/* Determines the maximum of the version-controlled modification times of
|
||||
+ FILENAMES[0..NFILES-1], and returns 0.
|
||||
+ Upon failure, it returns -1.
|
||||
+ NFILES must be > 0. */
|
||||
+extern int max_vc_mtime (struct timespec *max_of_mtimes,
|
||||
+ size_t nfiles, const char * const *filenames);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
--- a/modules/vc-mtime
|
||||
+++ b/modules/vc-mtime
|
||||
@@ -16,6 +16,17 @@ error
|
||||
getline
|
||||
xstrtol
|
||||
stat-time
|
||||
+filename
|
||||
+xalloc
|
||||
+xgetcwd
|
||||
+canonicalize-lgpl
|
||||
+xvasprintf
|
||||
+str_startswith
|
||||
+map
|
||||
+xmap
|
||||
+hash-map
|
||||
+hashkey-string
|
||||
+getdelim
|
||||
gettext-h
|
||||
gnulib-i18n
|
||||
|
91
tools/gnulib/patches/798-vc-mtime-add-api.patch
Normal file
91
tools/gnulib/patches/798-vc-mtime-add-api.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From f4c40c2d6aabef8e587176bbf5226c8bc6649574 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Fri, 2 May 2025 02:43:23 +0200
|
||||
Subject: [PATCH] vc-mtime: Add API for more efficient use of git, part 2.
|
||||
|
||||
* lib/vc-mtime.c (max_vc_mtime): Don't skip the odd-numbered arguments.
|
||||
---
|
||||
ChangeLog | 5 +++++
|
||||
lib/vc-mtime.c | 57 +++++++++++++++++++++-----------------------------
|
||||
2 files changed, 29 insertions(+), 33 deletions(-)
|
||||
|
||||
--- a/lib/vc-mtime.c
|
||||
+++ b/lib/vc-mtime.c
|
||||
@@ -558,17 +558,14 @@ max_vc_mtime (struct timespec *max_of_mt
|
||||
size_t n = n0;
|
||||
size_t cmd_len = 25;
|
||||
for (; n < nfiles; n++)
|
||||
- {
|
||||
- if (vc_controlled[n] == 1)
|
||||
- {
|
||||
- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
- && i > i0)
|
||||
- break;
|
||||
- argv[i++] = currdir_relative_filenames[n];
|
||||
- cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
- }
|
||||
- n++;
|
||||
- }
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
+ && i > i0)
|
||||
+ break;
|
||||
+ argv[i++] = currdir_relative_filenames[n];
|
||||
+ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
+ }
|
||||
if (i > i0)
|
||||
{
|
||||
pid_t child;
|
||||
@@ -672,17 +669,14 @@ max_vc_mtime (struct timespec *max_of_mt
|
||||
size_t n = n0;
|
||||
size_t cmd_len = 46;
|
||||
for (; n < nfiles; n++)
|
||||
- {
|
||||
- if (vc_controlled[n] == 1)
|
||||
- {
|
||||
- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
- && i > i0)
|
||||
- break;
|
||||
- argv[i++] = currdir_relative_filenames[n];
|
||||
- cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
- }
|
||||
- n++;
|
||||
- }
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
+ && i > i0)
|
||||
+ break;
|
||||
+ argv[i++] = currdir_relative_filenames[n];
|
||||
+ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
+ }
|
||||
if (i > i0)
|
||||
{
|
||||
pid_t child;
|
||||
@@ -768,17 +762,14 @@ max_vc_mtime (struct timespec *max_of_mt
|
||||
size_t n = n0;
|
||||
size_t cmd_len = 27;
|
||||
for (; n < nfiles; n++)
|
||||
- {
|
||||
- if (vc_controlled[n] == 1)
|
||||
- {
|
||||
- if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
- && i > i0)
|
||||
- break;
|
||||
- argv[i++] = currdir_relative_filenames[n];
|
||||
- cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
- }
|
||||
- n++;
|
||||
- }
|
||||
+ if (vc_controlled[n] == 1)
|
||||
+ {
|
||||
+ if (cmd_len + strlen (currdir_relative_filenames[n]) >= MAX_CMD_LEN
|
||||
+ && i > i0)
|
||||
+ break;
|
||||
+ argv[i++] = currdir_relative_filenames[n];
|
||||
+ cmd_len += 1 + strlen (currdir_relative_filenames[n]);
|
||||
+ }
|
||||
if (i > i0)
|
||||
{
|
||||
pid_t child;
|
125
tools/gnulib/patches/799-vc-mtime-old-git.patch
Normal file
125
tools/gnulib/patches/799-vc-mtime-old-git.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From 47548a77525a0f4489c9c420ccc2159079365da8 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Fri, 2 May 2025 12:09:40 +0200
|
||||
Subject: [PATCH] vc-mtime: Make it work with git versions < 2.28.
|
||||
|
||||
* lib/vc-mtime.c (git_version): New variable.
|
||||
(is_git_present): Read the output of "git --version", and set
|
||||
git_version.
|
||||
(max_vc_mtime): Don't pass option --no-relative if the git version
|
||||
is < 2.28.
|
||||
---
|
||||
ChangeLog | 9 ++++++
|
||||
lib/vc-mtime.c | 82 +++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
2 files changed, 83 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/lib/vc-mtime.c
|
||||
+++ b/lib/vc-mtime.c
|
||||
@@ -53,7 +53,9 @@
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
-/* Determines whether git is present. */
|
||||
+static const char *git_version;
|
||||
+
|
||||
+/* Determines whether git is present, and sets git_version if so. */
|
||||
static bool
|
||||
is_git_present (void)
|
||||
{
|
||||
@@ -63,17 +65,67 @@ is_git_present (void)
|
||||
if (!git_tested)
|
||||
{
|
||||
/* Test for presence of git:
|
||||
- "git --version >/dev/null 2>/dev/null" */
|
||||
+ "git --version 2>/dev/null" */
|
||||
const char *argv[3];
|
||||
- int exitstatus;
|
||||
+ pid_t child;
|
||||
+ int fd[1];
|
||||
|
||||
argv[0] = "git";
|
||||
argv[1] = "--version";
|
||||
argv[2] = NULL;
|
||||
- exitstatus = execute ("git", "git", argv, NULL, NULL,
|
||||
- false, false, true, true,
|
||||
- true, false, NULL);
|
||||
- git_present = (exitstatus == 0);
|
||||
+ child = create_pipe_in ("git", "git", argv, NULL, NULL,
|
||||
+ DEV_NULL, true, true, false, fd);
|
||||
+ if (child == -1)
|
||||
+ git_present = false;
|
||||
+ else
|
||||
+ {
|
||||
+ /* Retrieve its result. */
|
||||
+ FILE *fp = fdopen (fd[0], "r");
|
||||
+ if (fp == NULL)
|
||||
+ error (EXIT_FAILURE, errno, _("fdopen() failed"));
|
||||
+
|
||||
+ char *line = NULL;
|
||||
+ size_t linesize = 0;
|
||||
+ size_t linelen = getline (&line, &linesize, fp);
|
||||
+ if (linelen == (size_t)(-1))
|
||||
+ {
|
||||
+ fclose (fp);
|
||||
+ wait_subprocess (child, "git", true, true, true, false, NULL);
|
||||
+ git_present = false;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (linelen > 0 && line[linelen - 1] == '\n')
|
||||
+ line[linelen - 1] = '\0';
|
||||
+
|
||||
+ /* Read until EOF (otherwise the child process may get a SIGPIPE
|
||||
+ signal). */
|
||||
+ while (getc (fp) != EOF)
|
||||
+ ;
|
||||
+
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ /* Remove zombie process from process list, and retrieve exit
|
||||
+ status. */
|
||||
+ int exitstatus =
|
||||
+ wait_subprocess (child, "git", true, true, true, false, NULL);
|
||||
+ if (exitstatus != 0)
|
||||
+ {
|
||||
+ free (line);
|
||||
+ git_present = false;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* The version starts at the first digit in the line. */
|
||||
+ const char *p = line;
|
||||
+ for (; *p != '0'; p++)
|
||||
+ if (*p >= '0' && *p <= '9')
|
||||
+ break;
|
||||
+ git_version = p;
|
||||
+ git_present = true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
git_tested = true;
|
||||
}
|
||||
|
||||
@@ -660,7 +712,21 @@ max_vc_mtime (struct timespec *max_of_mt
|
||||
argv[i++] = "git";
|
||||
argv[i++] = "diff";
|
||||
argv[i++] = "--name-only";
|
||||
- argv[i++] = "--no-relative";
|
||||
+ /* With git versions >= 2.28, we pass option --no-relative,
|
||||
+ in order to neutralize any possible customization of the
|
||||
+ "diff.relative" property. With git versions < 2.28, this
|
||||
+ is not needed, and the option --no-relative does not
|
||||
+ exist. */
|
||||
+ if (!(git_version[0] <= '1'
|
||||
+ || (git_version[0] == '2' && git_version[1] == '.'
|
||||
+ && ((git_version[2] >= '0' && git_version[2] <= '9'
|
||||
+ && !(git_version[3] >= '0' && git_version[3] <= '9'))
|
||||
+ || (((git_version[2] == '1'
|
||||
+ && git_version[3] >= '0' && git_version[3] <= '9')
|
||||
+ || (git_version[2] == '2'
|
||||
+ && git_version[3] >= '0' && git_version[3] <= '7'))
|
||||
+ && !(git_version[4] >= '0' && git_version[4] <= '9'))))))
|
||||
+ argv[i++] = "--no-relative";
|
||||
argv[i++] = "-z";
|
||||
argv[i++] = "HEAD";
|
||||
argv[i++] = "--";
|
117
tools/gnulib/patches/900-str_startswith-module.patch
Normal file
117
tools/gnulib/patches/900-str_startswith-module.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 24010120fab36721caaf92be076655571e44da07 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Fri, 3 Jan 2025 09:26:14 +0100
|
||||
Subject: [PATCH] str_startswith: New module.
|
||||
|
||||
* lib/string.in.h (str_startswith): New declaration.
|
||||
* lib/str_startswith.c: New file.
|
||||
* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize
|
||||
GNULIB_STR_STARTSWITH.
|
||||
* modules/string-h (Makefile.am): Substitute GNULIB_STR_STARTSWITH.
|
||||
* modules/str_startswith: New file.
|
||||
---
|
||||
ChangeLog | 10 ++++++++++
|
||||
lib/str_startswith.c | 29 +++++++++++++++++++++++++++++
|
||||
lib/string.in.h | 8 ++++++++
|
||||
m4/string_h.m4 | 3 ++-
|
||||
modules/str_startswith | 23 +++++++++++++++++++++++
|
||||
modules/string-h | 1 +
|
||||
6 files changed, 73 insertions(+), 1 deletion(-)
|
||||
create mode 100644 lib/str_startswith.c
|
||||
create mode 100644 modules/str_startswith
|
||||
|
||||
--- /dev/null
|
||||
+++ b/lib/str_startswith.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* str_startswith function.
|
||||
+ Copyright (C) 2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include <string.h>
|
||||
+
|
||||
+
|
||||
+int
|
||||
+str_startswith (const char *string, const char *prefix)
|
||||
+{
|
||||
+ return strncmp (string, prefix, strlen (prefix)) == 0;
|
||||
+}
|
||||
--- a/lib/string.in.h
|
||||
+++ b/lib/string.in.h
|
||||
@@ -1079,6 +1079,14 @@ _GL_WARN_ON_USE (strtok_r, "strtok_r is
|
||||
/* The following functions are not specified by POSIX. They are gnulib
|
||||
extensions. */
|
||||
|
||||
+#if @GNULIB_STR_STARTSWITH@
|
||||
+/* Returns true if STRING starts with PREFIX.
|
||||
+ Returns false otherwise. */
|
||||
+_GL_EXTERN_C int str_startswith (const char *string, const char *prefix)
|
||||
+ _GL_ATTRIBUTE_PURE
|
||||
+ _GL_ARG_NONNULL ((1, 2));
|
||||
+#endif
|
||||
+
|
||||
#if @GNULIB_MBSLEN@
|
||||
/* Return the number of multibyte characters in the character string STRING.
|
||||
This considers multibyte characters, unlike strlen, which counts bytes. */
|
||||
--- a/m4/string_h.m4
|
||||
+++ b/m4/string_h.m4
|
||||
@@ -70,6 +70,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRSTR])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])
|
||||
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR])
|
||||
--- /dev/null
|
||||
+++ b/modules/str_startswith
|
||||
@@ -0,0 +1,23 @@
|
||||
+Description:
|
||||
+str_startswith() function: test whether a string starts with a given prefix.
|
||||
+
|
||||
+Files:
|
||||
+lib/str_startswith.c
|
||||
+
|
||||
+Depends-on:
|
||||
+string-h
|
||||
+
|
||||
+configure.ac:
|
||||
+gl_STRING_MODULE_INDICATOR([str_startswith])
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += str_startswith.c
|
||||
+
|
||||
+Include:
|
||||
+<string.h>
|
||||
+
|
||||
+License:
|
||||
+LGPLv2+
|
||||
+
|
||||
+Maintainer:
|
||||
+all
|
||||
--- a/modules/string-h
|
||||
+++ b/modules/string-h
|
||||
@@ -69,6 +69,7 @@ string.h: string.in.h $(top_builddir)/co
|
||||
-e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
|
||||
-e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \
|
||||
-e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
|
||||
+ -e 's/@''GNULIB_STR_STARTSWITH''@/$(GNULIB_STR_STARTSWITH)/g' \
|
||||
-e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
|
||||
-e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
|
||||
-e 's/@''GNULIB_STRERRORNAME_NP''@/$(GNULIB_STRERRORNAME_NP)/g' \
|
119
tools/gnulib/patches/901-str_endswith-module.patch
Normal file
119
tools/gnulib/patches/901-str_endswith-module.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From d89ac9373d9748f7601babf52c9129fcbcf0c907 Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Haible <bruno@clisp.org>
|
||||
Date: Fri, 3 Jan 2025 09:54:14 +0100
|
||||
Subject: [PATCH] str_endswith: New module.
|
||||
|
||||
* lib/string.in.h (str_endswith): New declaration.
|
||||
* lib/str_endswith.c: New file.
|
||||
* m4/string_h.m4 (gl_STRING_H_REQUIRE_DEFAULTS): Initialize
|
||||
GNULIB_STR_ENDSWITH.
|
||||
* modules/string-h (Makefile.am): Substitute GNULIB_STR_ENDSWITH.
|
||||
* modules/str_endswith: New file.
|
||||
---
|
||||
ChangeLog | 10 ++++++++++
|
||||
lib/str_endswith.c | 31 +++++++++++++++++++++++++++++++
|
||||
lib/string.in.h | 8 ++++++++
|
||||
m4/string_h.m4 | 3 ++-
|
||||
modules/str_endswith | 23 +++++++++++++++++++++++
|
||||
modules/string-h | 1 +
|
||||
6 files changed, 75 insertions(+), 1 deletion(-)
|
||||
create mode 100644 lib/str_endswith.c
|
||||
create mode 100644 modules/str_endswith
|
||||
|
||||
--- /dev/null
|
||||
+++ b/lib/str_endswith.c
|
||||
@@ -0,0 +1,31 @@
|
||||
+/* str_endswith function.
|
||||
+ Copyright (C) 2025 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is free software: you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* Written by Bruno Haible <bruno@clisp.org>, 2025. */
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+/* Specification. */
|
||||
+#include <string.h>
|
||||
+
|
||||
+
|
||||
+int
|
||||
+str_endswith (const char *string, const char *suffix)
|
||||
+{
|
||||
+ size_t len = strlen (string);
|
||||
+ size_t n = strlen (suffix);
|
||||
+ return len >= n && strcmp (string + len - n, suffix) == 0;
|
||||
+}
|
||||
--- a/lib/string.in.h
|
||||
+++ b/lib/string.in.h
|
||||
@@ -1087,6 +1087,14 @@ _GL_EXTERN_C int str_startswith (const c
|
||||
_GL_ARG_NONNULL ((1, 2));
|
||||
#endif
|
||||
|
||||
+#if @GNULIB_STR_ENDSWITH@
|
||||
+/* Returns true if STRING ends with SUFFIX.
|
||||
+ Returns false otherwise. */
|
||||
+_GL_EXTERN_C int str_endswith (const char *string, const char *prefix)
|
||||
+ _GL_ATTRIBUTE_PURE
|
||||
+ _GL_ARG_NONNULL ((1, 2));
|
||||
+#endif
|
||||
+
|
||||
#if @GNULIB_MBSLEN@
|
||||
/* Return the number of multibyte characters in the character string STRING.
|
||||
This considers multibyte characters, unlike strlen, which counts bytes. */
|
||||
--- a/m4/string_h.m4
|
||||
+++ b/m4/string_h.m4
|
||||
@@ -71,6 +71,7 @@ AC_DEFUN([gl_STRING_H_REQUIRE_DEFAULTS],
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRCASESTR])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STRTOK_R])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_STARTSWITH])
|
||||
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STR_ENDSWITH])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSLEN])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSNLEN])
|
||||
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MBSCHR])
|
||||
--- /dev/null
|
||||
+++ b/modules/str_endswith
|
||||
@@ -0,0 +1,23 @@
|
||||
+Description:
|
||||
+str_endswith() function: test whether a string ends with a given suffix.
|
||||
+
|
||||
+Files:
|
||||
+lib/str_endswith.c
|
||||
+
|
||||
+Depends-on:
|
||||
+string-h
|
||||
+
|
||||
+configure.ac:
|
||||
+gl_STRING_MODULE_INDICATOR([str_endswith])
|
||||
+
|
||||
+Makefile.am:
|
||||
+lib_SOURCES += str_endswith.c
|
||||
+
|
||||
+Include:
|
||||
+<string.h>
|
||||
+
|
||||
+License:
|
||||
+LGPLv2+
|
||||
+
|
||||
+Maintainer:
|
||||
+all
|
||||
--- a/modules/string-h
|
||||
+++ b/modules/string-h
|
||||
@@ -69,6 +69,7 @@ string.h: string.in.h $(top_builddir)/co
|
||||
-e 's/@''GNULIB_STRSTR''@/$(GNULIB_STRSTR)/g' \
|
||||
-e 's/@''GNULIB_STRCASESTR''@/$(GNULIB_STRCASESTR)/g' \
|
||||
-e 's/@''GNULIB_STRTOK_R''@/$(GNULIB_STRTOK_R)/g' \
|
||||
+ -e 's/@''GNULIB_STR_ENDSWITH''@/$(GNULIB_STR_ENDSWITH)/g' \
|
||||
-e 's/@''GNULIB_STR_STARTSWITH''@/$(GNULIB_STR_STARTSWITH)/g' \
|
||||
-e 's/@''GNULIB_STRERROR''@/$(GNULIB_STRERROR)/g' \
|
||||
-e 's/@''GNULIB_STRERROR_R''@/$(GNULIB_STRERROR_R)/g' \
|
@ -14,8 +14,6 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
|
||||
PKG_HASH:=da8ebb2ce4dcf46b90098daf962cffa68f4b4f62ea60f798d0ef12929ede6adf
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
export GNULIB_SRCDIR:=$(HOST_GNULIB_SRCDIR)
|
||||
@ -23,6 +21,10 @@ export GNULIB_SRCDIR:=$(HOST_GNULIB_SRCDIR)
|
||||
HOST_CONFIGURE_VARS += \
|
||||
lt_cv_sys_dlsearch_path=""
|
||||
|
||||
HOST_MAKE_FLAGS += \
|
||||
am__CONFIG_DISTCLEAN_FILES= \
|
||||
CONFIG_STATUS_DEPENDENCIES=
|
||||
|
||||
define Host/Bootstrap
|
||||
( \
|
||||
cd $(HOST_BUILD_DIR); \
|
||||
@ -45,6 +47,7 @@ endef
|
||||
define Host/Configure
|
||||
$(if $(QUILT),$(call Host/Bootstrap))
|
||||
$(call Host/Configure/Default)
|
||||
$(call Host/Uninstall)
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
@ -54,6 +57,7 @@ endef
|
||||
|
||||
define Host/Uninstall
|
||||
-$(call Host/Compile/Default,uninstall)
|
||||
-$(call Host/Compile/Default,maintainer-clean) # Clean bootstrap files from the release
|
||||
(cd $(STAGING_DIR_HOST)/share/aclocal/ && rm -f libtool.m4 ltdl.m4 lt~obsolete.m4 ltoptions.m4 ltsugar.m4 ltversion.m4)
|
||||
endef
|
||||
|
||||
|
13
tools/util-linux/patches/102-macos-uuid-next.patch
Normal file
13
tools/util-linux/patches/102-macos-uuid-next.patch
Normal file
@ -0,0 +1,13 @@
|
||||
--- a/libuuid/src/uuid.h
|
||||
+++ b/libuuid/src/uuid.h
|
||||
@@ -35,6 +35,10 @@
|
||||
#ifndef _UL_LIBUUID_UUID_H
|
||||
#define _UL_LIBUUID_UUID_H
|
||||
|
||||
+#if defined(__clang__) && defined(__APPLE__)
|
||||
+#include_next <uuid/uuid.h>
|
||||
+#endif
|
||||
+
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
Reference in New Issue
Block a user