Compare commits
16 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5e4a202878 | ||
![]() |
9e05bce08b | ||
![]() |
387813dffc | ||
![]() |
4399d10abb | ||
![]() |
e113722e68 | ||
![]() |
a9ecd6716d | ||
![]() |
d0f1242751 | ||
![]() |
441a0599ce | ||
![]() |
08734804d6 | ||
![]() |
d80003ff1d | ||
![]() |
62c2ab897d | ||
![]() |
7617a35cbc | ||
![]() |
fd4713eb1e | ||
![]() |
b0a683e4fb | ||
![]() |
7100bf5963 | ||
![]() |
c037071164 |
540 changed files with 118155 additions and 148031 deletions
42
Makefile
42
Makefile
|
@ -19,20 +19,21 @@ dirs += sys
|
|||
ifeq ($(arch),x86_64)
|
||||
dirs += lib64
|
||||
endif
|
||||
alldirs += $(dirs)
|
||||
alldirs += bin
|
||||
alldirs += boot
|
||||
basedirs += $(dirs)
|
||||
basedirs += bin
|
||||
basedirs += boot
|
||||
basedirs += home
|
||||
basedirs += lib
|
||||
basedirs += media
|
||||
basedirs += mnt
|
||||
basedirs += opt
|
||||
basedirs += root
|
||||
basedirs += sbin
|
||||
basedirs += srv
|
||||
basedirs += tmp
|
||||
basedirs += usr
|
||||
alldirs += $(basedirs)
|
||||
alldirs += etc
|
||||
alldirs += home
|
||||
alldirs += lib
|
||||
alldirs += media
|
||||
alldirs += mnt
|
||||
alldirs += opt
|
||||
alldirs += root
|
||||
alldirs += sbin
|
||||
alldirs += srv
|
||||
alldirs += tmp
|
||||
alldirs += usr
|
||||
alldirs += var
|
||||
|
||||
all: buildworld
|
||||
|
@ -123,6 +124,12 @@ rootfs-tbz: rootfs-hhl-$(os_version)-$(arch).tbz
|
|||
|
||||
rootfs-txz: rootfs-hhl-$(os_version)-$(arch).txz
|
||||
|
||||
rootfs-updte-tgz: rootfs-hhl-update-$(os_version)-$(arch).tgz
|
||||
|
||||
rootfs-updte-tbz: rootfs-hhl-update-$(os_version)-$(arch).tbz
|
||||
|
||||
rootfs-updte-txz: rootfs-hhl-update-$(os_version)-$(arch).txz
|
||||
|
||||
.PHONY: rootfs-tgz rootfs-tbz rootfs-txz
|
||||
|
||||
toolchain-hhl-$(os_version)-$(arch).tgz: $(tooldir)/.built smalltools
|
||||
|
@ -143,6 +150,15 @@ rootfs-hhl-$(os_version)-$(arch).tbz: $(plists) $(build)/.stripped
|
|||
rootfs-hhl-$(os_version)-$(arch).txz: $(plists) $(build)/.stripped
|
||||
cd $(build) && paxtar -M uidgid -cJf $(basedir)/$@ $(alldirs)
|
||||
|
||||
rootfs-hhl-update-$(os_version)-$(arch).tgz: $(plists) $(build)/.stripped
|
||||
cd $(build) && paxtar -M uidgid -czf $(basedir)/$@ $(basedirs)
|
||||
|
||||
rootfs-hhl-update-$(os_version)-$(arch).tbz: $(plists) $(build)/.stripped
|
||||
cd $(build) && paxtar -M uidgid -cjf $(basedir)/$@ $(basedirs)
|
||||
|
||||
rootfs-hhl-update-$(os_version)-$(arch).txz: $(plists) $(build)/.stripped
|
||||
cd $(build) && paxtar -M uidgid -cJf $(basedir)/$@ $(basedirs)
|
||||
|
||||
remove-toolchain:
|
||||
$(MAKE) -C toolchain remove
|
||||
|
||||
|
|
38
config.mk
Normal file
38
config.mk
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Target architecture, IE the machine that the newly built system will run on. Supported targets are: i486
|
||||
# i586
|
||||
# i686
|
||||
# x86_64 (most modern Intel and AMD based systems)
|
||||
# armv7l (earlier Arm SBC's such as RPI and RPI2)
|
||||
# aarch64 (later Arm SBC's such as RPI3 and RPI4)
|
||||
# riscv64 (SiFive Unmatched, BeagleV)
|
||||
arch = x86_64
|
||||
|
||||
# If building for rpi3/4 we can automatically configure and build u-boot
|
||||
# by setting rpi to 1
|
||||
# rpi = 1
|
||||
|
||||
# Maximum make threads to run concurrently. For some packages on some
|
||||
# architectures this will be automatically overridden.
|
||||
makeflags = -j8
|
||||
|
||||
# Optional bootstrap packages. HitchHiker ships with BSD paxtar, and it's syntax
|
||||
# is used rather than GNU tar in certain places. To bootstrap on systems other
|
||||
# than HitchHiker it is a good idea to set build_pax to 1.
|
||||
build_pax = 0
|
||||
|
||||
# If building on HitchHiker, Perl will need to be built as it is used repeatedly
|
||||
# during the build of other packages. If perl is installed via pkgsrc this can
|
||||
# be skipped.
|
||||
build_perl = 0
|
||||
|
||||
# If building on HitchHiker, intltool is not part of the base system as it
|
||||
# depends on the XML::Parser perl module.
|
||||
build_intltool = 0
|
||||
|
||||
# Again, if building on HitchHiker, Python must be built either here or via
|
||||
# pkgsrc.
|
||||
build_python = 0
|
||||
|
||||
# If the version of `file` installed on the host differs from the one supplied
|
||||
# by HitchHiker, it may be necessary to build `file` as well
|
||||
build_file = 1
|
|
@ -21,6 +21,7 @@ binutils-${binutils_version}.tar.xz \
|
|||
bison-${bison_version}.tar.xz \
|
||||
busybox-${busybox_version}.tar.bz2 \
|
||||
bzip2-${bzip2_version}.tar.gz \
|
||||
ca-certificates_$(ca-certificates_version).tar.xz \
|
||||
cmake-$(cmake_version).tar.gz \
|
||||
coreutils-${coreutils_version}.tar.xz \
|
||||
dash-${dash_version}.tar.gz \
|
||||
|
@ -73,6 +74,7 @@ mpc-${mpc_version}.tar.gz \
|
|||
mpfr-${mpfr_version}.tar.xz \
|
||||
musl-$(musl_version).tar.gz \
|
||||
musl-fts-$(musl-fts_version).tar.gz \
|
||||
musl-obstack-$(musl-obstack_version).tar.gz \
|
||||
openssl-${openssl_version}.tar.gz \
|
||||
ncurses-${ncurses_version}.tar.gz \
|
||||
netbsd-curses-${netbsd-curses_version}.tar.xz \
|
||||
|
@ -161,6 +163,11 @@ bzip2: bzip2-${bzip2_version}.tar.gz
|
|||
bzip2-${bzip2_version}.tar.gz:
|
||||
wget -c https://www.sourceware.org/pub/bzip2/$@
|
||||
|
||||
ca-certificates: ca-certificates_$(ca-certificats_version).tar.xz
|
||||
|
||||
ca-certificates_$(ca-certificates_version).tar.xz:
|
||||
wget -c http://deb.debian.org/debian/pool/main/c/ca-certificates/$@
|
||||
|
||||
cmake: cmake-$(cmake_version).tar.gz
|
||||
|
||||
cmake-$(cmake_version).tar.gz:
|
||||
|
@ -432,6 +439,12 @@ musl-fts-$(musl-fts_version).tar.gz:
|
|||
wget -c $(github)/void-linux/musl-fts/archive/v$(musl-fts_version).tar.gz \
|
||||
-O $@
|
||||
|
||||
musl-obstack: musl-obstack-$(musl-obstack_version).tar.gz
|
||||
|
||||
musl-obstack-$(musl-obstack_version).tar.gz:
|
||||
wget -c $(github)/void-linux/musl-obstack/archive/v$(musl-obstack_version).tar.gz \
|
||||
-O $@
|
||||
|
||||
ncurses: ncurses-${ncurses_version}.tar.gz
|
||||
|
||||
ncurses-${ncurses_version}.tar.gz:
|
||||
|
@ -507,20 +520,20 @@ s6: s6-${s6_version}.tar.gz
|
|||
s6-${s6_version}.tar.gz:
|
||||
wget -c ${skarnet}/s6/$@
|
||||
|
||||
s6-linux-init: s6-linux-init-${s6-linux-init_version}.tar.gz
|
||||
s6-linux-init: s6-linux-init-$(s6-linux-init_version).tar.gz
|
||||
|
||||
s6-linux-init-${s6-linux-init_version}.tar.gz:
|
||||
wget -c ${skarnet}/s6-linux-init/$@
|
||||
s6-linux-init-$(s6-linux-init_version).tar.gz:
|
||||
wget -c $(skarnet)/s6-linux-init/$@
|
||||
|
||||
s6-rc: s6-rc-${s6-rc_version}.tar.gz
|
||||
|
||||
s6-rc-${s6-rc_version}.tar.gz:
|
||||
wget -c ${skarnet}/s6-rc/$@
|
||||
|
||||
sed: sed-${sed_version}.tar.xz
|
||||
sed: sed-$(sed_version).tar.xz
|
||||
|
||||
sed-${sed_version}.tar.xz:
|
||||
wget -c ${gnu}/sed/$@
|
||||
sed-$(sed_version).tar.xz:
|
||||
wget -c $(gnu)/sed/$@
|
||||
|
||||
shadow: shadow-${shadow_version}.tar.xz
|
||||
|
||||
|
|
|
@ -21,34 +21,33 @@ srv \
|
|||
sys \
|
||||
sys \
|
||||
tmp \
|
||||
usr \
|
||||
var
|
||||
usr
|
||||
|
||||
install: ${pkgdbdir}/plist ${pkgdbdir}/etc.plist
|
||||
|
||||
${pkgdbdir}/plist:
|
||||
if [ ! -d ${pkgdbdir} ] ; then install -d ${pkgdbdir} ; fi
|
||||
find usr/src -name '.built' -exec rm -rf {} + || true
|
||||
find usr/src -name '.installed' -exec rm -rf {} + || true
|
||||
find ${dirs} -type f | while read f ; \
|
||||
do echo file\|$$(stat -c %n\|%a\|root:root $${f})\|$$(file -b -e elf $${f}) ; \
|
||||
do echo file\|$$(stat -c %n\|%a\|root:root "$${f}")\|$$(file -b -e elf "$${f}") ; \
|
||||
done > $@.in
|
||||
find ${dirs} -type d | while read d ; \
|
||||
do echo directory\|$$(stat -c %n\|%a\|root:root $${d}) ; \
|
||||
do echo directory\|$$(stat -c %n\|%a\|root:root "$${d}") ; \
|
||||
done >> $@.in
|
||||
find ${dirs} -type c | while read c ; \
|
||||
do echo device\|$${c}\|$$(file -b $${c}) ; \
|
||||
do echo device\|$${c}\|$$(file -b "$${c}") ; \
|
||||
done >> $@.in
|
||||
mv -v $@.in $@
|
||||
sort -u $@.in > $@
|
||||
rm -rf $@.in
|
||||
|
||||
${pkgdbdir}/etc.plist:
|
||||
if [ ! -d ${pkgdbdir} ] ; then install -d ${pkgdbdir} ; fi
|
||||
find etc -type f | while read f ; \
|
||||
do echo file\|$$(stat -c %n\|%a\|root:root $${f})\|$$(file -b -e elf $${f}) ; \
|
||||
find etc var -type f | while read f ; \
|
||||
do echo file\|$$(stat -c %n\|%a\|root:root "$${f}")\|$$(file -b -e elf "$${f}") ; \
|
||||
done > $@.in
|
||||
find etc -type d | while read d ; \
|
||||
do echo directory\|$$(stat -c %n\|%a\|root:root $${d}) ; \
|
||||
find etc var -type d | while read d ; \
|
||||
do echo directory\|$$(stat -c %n\|%a\|root:root "$${d}") ; \
|
||||
done >> $@.in
|
||||
mv -v $@.in $@
|
||||
sort -u $@.in > $@
|
||||
rm -rf $@.in
|
||||
|
||||
.PHONY: install
|
||||
|
|
40
include/mk/hhl.cargo.mk
Normal file
40
include/mk/hhl.cargo.mk
Normal file
|
@ -0,0 +1,40 @@
|
|||
# hhl.cargo.mk
|
||||
# Copyright 2023 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
include world.mk
|
||||
include hhl.doc.mk
|
||||
include hhl.locale.mk
|
||||
include hhl.colors.mk
|
||||
|
||||
ifeq ($(arch), riscv64)
|
||||
rust_tgt = riscv64gc-unknown-linux-musl
|
||||
CARGO = cargo +nightly
|
||||
BUILD_STD = -Zbuild-std=std,panic_abort
|
||||
else
|
||||
rust_tgt = $(arch)-unknown-linux-musl
|
||||
CARGO = cargo
|
||||
endif
|
||||
INSTALL ?= install $(perms) $(cargo_out) $(bindir)/
|
||||
|
||||
tgt_dir = $(global_objdir)/$(progname)/target
|
||||
export CARGO_TARGET_DIR = $(tgt_dir)
|
||||
|
||||
cargo_out = $(patsubst %,$(tgt_dir)/$(rust_tgt)/release/%,$(bins))
|
||||
|
||||
install: $(cargo_out) $(docs) $(locales) | $(bindir)
|
||||
$(INSTALL)
|
||||
$(info $(grn)=== Finished building $(progname) ===$(reset))
|
||||
|
||||
$(bindir):
|
||||
install -d $@
|
||||
|
||||
$(cargo_out):
|
||||
$(info $(grn)=== Building for ${progname} ===$(reset))
|
||||
${pre_build}
|
||||
$(CARGO) build $(BUILD_STD) $(FEATURES) --target=$(rust_tgt) --release
|
||||
${post_build}
|
||||
|
||||
clean:
|
||||
cargo clean
|
||||
|
||||
.PHONY: install clean
|
|
@ -3,10 +3,10 @@
|
|||
#
|
||||
internal = true
|
||||
src ?= ./src
|
||||
objdir ?= ${global_objdir}/${progname}
|
||||
srcs += $(wildcard ${src}/*.c)
|
||||
objs += $(patsubst ${src}/%.c,${objdir}/%.o,${srcs})
|
||||
hdrs += $(wildcard ${src}/*.h)
|
||||
objdir ?= $(global_objdir)/$(progname)
|
||||
srcs ?= $(wildcard $(src)/*.c)
|
||||
objs ?= $(patsubst $(src)/%.c,$(objdir)/%.o,$(srcs))
|
||||
hdrs ?= $(wildcard $(src)/*.h)
|
||||
o_lvl ?= -O2
|
||||
include world.mk
|
||||
include hhl.doc.mk
|
||||
|
@ -17,26 +17,26 @@ AR = $(tgt)-ar
|
|||
RANLIB = $(tgt)-ranlib
|
||||
BLD_CC ?= cc
|
||||
|
||||
ifeq (${sbin},1)
|
||||
bindir = ${sbindir}
|
||||
binprog = ${sbindir}/${progname}
|
||||
ifeq ($(sbin),1)
|
||||
bindir = $(sbindir)
|
||||
binprog = $(sbindir)/$(progname)
|
||||
else
|
||||
binprog = ${bindir}/${progname}
|
||||
binprog = $(bindir)/$(progname)
|
||||
endif
|
||||
|
||||
ldflags += -I${src}
|
||||
cflags += ${o_lvl}
|
||||
ldflags += -I$(src)
|
||||
cflags += $(o_lvl)
|
||||
cflags += --sysroot=$(DESTDIR)
|
||||
|
||||
ifeq (${hhl_source},1)
|
||||
ifeq ($(hhl_source),1)
|
||||
cflags += -std=c99
|
||||
cflags += -Wall
|
||||
cflags += -pedantic
|
||||
endif
|
||||
|
||||
VPATH += ${src}
|
||||
VPATH += $(src)
|
||||
|
||||
install: ${binprog} ${docs} ${locales} | ${binlinks} ${manlinks}
|
||||
install: $(binprog) $(docs) $(locales) | $(binlinks) $(manlinks)
|
||||
$(info $(grn)=== Finished building $(progname) ===$(reset))
|
||||
|
||||
ifeq (${onestage},true)
|
||||
|
@ -59,10 +59,10 @@ ${objdir}/%.o: ${src}/%.c ${hdrs} | ${objdir}
|
|||
$(CC) ${cppflags} ${cflags} ${ldflags} -o $@ -c $<
|
||||
endif
|
||||
|
||||
${binlinks}: ${binprog}
|
||||
ln -sf ${progname} $@
|
||||
$(binlinks): $(binprog)
|
||||
ln -sf $(progname) $@
|
||||
|
||||
${bindir}:
|
||||
$(bindir):
|
||||
install -d $@
|
||||
|
||||
clean:
|
||||
|
|
|
@ -21,6 +21,7 @@ $(objdir):
|
|||
install -d $(objdir)
|
||||
|
||||
install: $(libdir)/$(staticlib)
|
||||
$(post_install)
|
||||
|
||||
$(libdir)/$(staticlib): $(staticlib) | $(libdir)
|
||||
install $< $@
|
||||
|
|
|
@ -16,22 +16,11 @@ include hhl.colors.mk
|
|||
endif
|
||||
|
||||
ifeq ($(filter armv6 armv7l aarch64, $(arch)), $(arch))
|
||||
tgt = $(arch)-unknown-linux-gnueabi
|
||||
tgt = $(arch)-hitchhiker-linux-musleabihf
|
||||
else
|
||||
tgt = $(arch)-unknown-linux-gnu
|
||||
tgt = $(arch)-hitchhiker-linux-musl
|
||||
endif
|
||||
|
||||
ifeq ($(filter armv7l aarch64, $(bld_arch)), $(bld_arch))
|
||||
bld = $(bld_arch)-unknown-linux-gnueabi
|
||||
else
|
||||
bld = $(bld_arch)-unknown-linux-gnu
|
||||
endif
|
||||
#ifeq ($(filter armv6 armv7l aarch64, $(arch)), $(arch))
|
||||
#tgt = $(arch)-hitchhiker-linux-musleabihf
|
||||
#else
|
||||
#tgt = $(arch)-hitchhiker-linux-musl
|
||||
#endif
|
||||
#bld = $(shell gcc -dumpmachine)
|
||||
bld = $(shell gcc -dumpmachine)
|
||||
|
||||
exec_prefix ?= ${DESTDIR}${install_prefix}
|
||||
bindir ?= ${exec_prefix}/bin
|
||||
|
|
|
@ -9,10 +9,11 @@ attr_version = 2.5.1
|
|||
autoconf_version = 2.71
|
||||
automake_version = 1.16.5
|
||||
bc_version = 6.0.1
|
||||
binutils_version = 2.39
|
||||
binutils_version = 2.41
|
||||
bison_version = 3.8.2
|
||||
busybox_version = 1.31.1
|
||||
bzip2_version = 1.0.8
|
||||
ca-certificates_version = 20240203
|
||||
cmake_version = 3.18.1
|
||||
coreutils_version = 8.32
|
||||
curl_version = 7.84.0
|
||||
|
@ -23,21 +24,21 @@ dhcpcd_version = 9.4.1
|
|||
e2fsprogs_version = 1.46.5
|
||||
elfutils_version = 0.187
|
||||
eudev_version = 3.2.11
|
||||
execline_version = 2.9.0.1
|
||||
execline_version = 2.9.1.0
|
||||
expat_version = 2.4.8
|
||||
file_version = 5.43
|
||||
findutils_version = 4.9.0
|
||||
flex_version = 2.6.4
|
||||
gawk_version = 5.1.1
|
||||
gcc_version = 12.2.0
|
||||
gcc_version = 13.2.0
|
||||
gdbm_version = 1.23
|
||||
gettext_version = 0.21
|
||||
gettext-tiny_version = 0.3.2
|
||||
glibc_version = 2.36
|
||||
gmp_version = 6.2.1
|
||||
gperf_version = 3.1
|
||||
grep_version = 3.7
|
||||
groff_version = 1.22.4
|
||||
grep_version = 3.8
|
||||
groff_version = 1.23.0
|
||||
grub_version = 2.06
|
||||
gzip_version = 1.12
|
||||
haveged_version = 1.9.18
|
||||
|
@ -56,7 +57,7 @@ libnl_version = 3.5.0
|
|||
libressl_version = 3.0.2
|
||||
libtool_version = 2.4.7
|
||||
libz_version = 1.2.8.2015.12.26
|
||||
linux_version = 6.1.1
|
||||
linux_version = 6.4.11
|
||||
linux-firmware_version = 20220815
|
||||
linux_rpi_version = 5.4.45
|
||||
m4_version = 1.4.19
|
||||
|
@ -66,8 +67,9 @@ mandoc_version = 1.14.5
|
|||
meson_version = 0.61.1
|
||||
mpc_version = 1.2.1
|
||||
mpfr_version = 4.1.0
|
||||
musl_version = 1.2.2
|
||||
musl_version = 1.2.4
|
||||
musl-fts_version = 1.2.7
|
||||
musl-obstack_version = 1.2.3
|
||||
ncurses_version = 6.3
|
||||
netbsd-curses_version = 0.3.1
|
||||
ninja_version = 1.11.0
|
||||
|
@ -79,26 +81,26 @@ perl-cross_version = 1.3.5
|
|||
pkg-config_version = 0.29.2
|
||||
pkgsrc_version = 2022Q2
|
||||
procps-ng_version = 3.3.16
|
||||
psmisc_version = 23.5
|
||||
psmisc_version = 23.6
|
||||
python_version = 3.10.6
|
||||
s6_version = 2.11.1.2
|
||||
s6-linux-init_version = 1.0.8.0
|
||||
s6-rc_version = 0.5.3.2
|
||||
sed_version = 4.8
|
||||
s6_version = 2.11.2.0
|
||||
s6-linux-init_version = 1.0.8.1
|
||||
s6-rc_version = 0.5.3.3
|
||||
sed_version = 4.9
|
||||
shadow_version = 4.12.2
|
||||
skalibs_version = 2.12.0.1
|
||||
skalibs_version = 2.13.0.0
|
||||
sysklogd_version = 1.5.1
|
||||
tar_version = 1.34
|
||||
texinfo_version = 6.8
|
||||
tzdata_version = 2022c
|
||||
u-boot_version = 2021.01
|
||||
udev-lfs_version = 20171102
|
||||
util-linux_version = 2.36.1
|
||||
util-linux_version = 2.38.1
|
||||
vim_version = 8.2.2433
|
||||
wget_version = 1.21.3
|
||||
wireless_tools_version = 29
|
||||
wpa_supplicant_version = 2.9
|
||||
XML-Parser_version = 2.46
|
||||
xz_version = 5.2.6
|
||||
zsh_version = 5.8.1
|
||||
zsh_version = 5.9
|
||||
zstd_version = 1.5.2
|
||||
|
|
10788
kernel/config-x86_64-6.1.12.config
Normal file
10788
kernel/config-x86_64-6.1.12.config
Normal file
File diff suppressed because it is too large
Load diff
10883
kernel/config-x86_64-6.4.11.config
Normal file
10883
kernel/config-x86_64-6.4.11.config
Normal file
File diff suppressed because it is too large
Load diff
|
@ -4,9 +4,6 @@
|
|||
|
||||
include toolchain.mk
|
||||
|
||||
ifeq ($(build_gawk), 1)
|
||||
subdirs += gawk
|
||||
endif
|
||||
ifeq ($(build_pax), 1)
|
||||
subdirs += pax
|
||||
endif
|
||||
|
@ -23,9 +20,12 @@ endif
|
|||
subdirs += binutils
|
||||
subdirs += gcc-pass1
|
||||
subdirs += linux-headers
|
||||
subdirs += glibc
|
||||
#subdirs += musl
|
||||
#subdirs += glibc
|
||||
subdirs += musl
|
||||
subdirs += gcc-pass2
|
||||
subdirs += pkg-config
|
||||
subdirs += autoconf
|
||||
subdirs += automake
|
||||
|
||||
installdirs += $(tooldir) $(global_srcdir) $(global_objdir)
|
||||
|
||||
|
|
6
toolchain/autoconf/Makefile
Normal file
6
toolchain/autoconf/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Makefile - hhl - /usr/src/world/autoconf
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
distname = autoconf
|
||||
include toolchain.mk
|
||||
include targets.mk
|
6
toolchain/automake/Makefile
Normal file
6
toolchain/automake/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Makefile - hhl - /usr/src/world/automake
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
distname = automake
|
||||
include toolchain.mk
|
||||
include targets.mk
|
|
@ -4,5 +4,4 @@
|
|||
distname = file
|
||||
distext = gz
|
||||
include toolchain.mk
|
||||
config_opts += --disable-nls
|
||||
include targets.mk
|
||||
|
|
|
@ -3,17 +3,13 @@
|
|||
#
|
||||
distname = gcc
|
||||
include toolchain.mk
|
||||
objdir = $(global_objdir)/gcc-pass2
|
||||
objdir = $(global_objdir)/gcc-pass2
|
||||
config_opts += --target=$(tgt)
|
||||
config_opts += --with-sysroot=$(build)
|
||||
config_opts += --with-glibc-version=2.11
|
||||
config_opts += --enable-languages=c,c++
|
||||
config_opts += --enable-languages=c,c++,fortran
|
||||
config_opts += --disable-multilib
|
||||
config_opts += --disable-bootstrap
|
||||
# For musl
|
||||
#config_opts += --disable-libsanitizer
|
||||
ifneq ($(filter i686 x86_64, $(arch)), $(arch))
|
||||
config_opts += --disable-libsanitizer
|
||||
endif
|
||||
|
||||
include targets.mk
|
||||
|
|
|
@ -10,4 +10,7 @@ config_opts += --host=$(tgt)
|
|||
config_opts += --bindir=/bin
|
||||
|
||||
include targets.mk
|
||||
$(srcdir)/.dirstamp: | $(global_srcdir)
|
||||
|
||||
$(global_srcdir):
|
||||
install -d $@
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Makefile - hhl - /usr/src/world/pax
|
||||
# Makefile - hhl - /usr/src/toolchain/pax
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
include ../../config.mk
|
||||
|
|
32
toolchain/pkg-config/Makefile
Normal file
32
toolchain/pkg-config/Makefile
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Makefile - hhl - /usr/src/toolchain/pax
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
include ../../config.mk
|
||||
progname = $(arch)-pkg-config
|
||||
bindir = $(tooldir)/bin
|
||||
objdir = $(global_objdir)/pkg-config
|
||||
|
||||
srcs += src/pkg-config.sh
|
||||
objs += $(objdir)/$(arch)-pkg-config
|
||||
include toolchain.mk
|
||||
|
||||
install: $(bindir)/$(progname)
|
||||
$(info $(grn)=== Finished building for $(progname) ===$(reset))
|
||||
|
||||
$(bindir)/$(progname): $(objs) | $(bindir)
|
||||
install -vm0755 $< $@
|
||||
|
||||
$(objs): $(srcs) | $(objdir)
|
||||
sed "s:@@SYSROOT@@:$(build):" $< > $@
|
||||
|
||||
$(bindir):
|
||||
install -d $@
|
||||
|
||||
$(objdir):
|
||||
$(info $(grn)=== Building for $(progname) ===$(reset))
|
||||
install -d $@
|
||||
|
||||
clean:
|
||||
rm -rf $(objdir)
|
||||
|
||||
.PHONY: install clean
|
9
toolchain/pkg-config/src/pkg-config.sh
Normal file
9
toolchain/pkg-config/src/pkg-config.sh
Normal file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
SYSROOT=@@SYSROOT@@
|
||||
|
||||
export PKG_CONFIG_PATH=
|
||||
export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig
|
||||
export PKG_CONFIG_SYSROOT_DIR=${SYSROOT}
|
||||
|
||||
exec pkg-config "$@"
|
|
@ -35,26 +35,23 @@ subdirs += gdbm
|
|||
subdirs += pcre
|
||||
subdirs += zsh
|
||||
subdirs += inetutils
|
||||
#subdirs += perl
|
||||
subdirs += autoconf
|
||||
subdirs += automake
|
||||
subdirs += gperf
|
||||
#subdirs += gperf
|
||||
subdirs += expat
|
||||
#subdirs += xml-parser
|
||||
#subdirs += intltool
|
||||
subdirs += kmod
|
||||
subdirs += gettext
|
||||
# for musl
|
||||
#subdirs += argp-standalone
|
||||
subdirs += argp-standalone
|
||||
# for musl
|
||||
subdirs += musl-fts
|
||||
# for musl
|
||||
subdirs += musl-obstack
|
||||
subdirs += elfutils
|
||||
subdirs += libffi
|
||||
subdirs += gawk
|
||||
#subdirs += libressl
|
||||
subdirs += openssl
|
||||
subdirs += wget
|
||||
#subdirs += python
|
||||
#subdirs += ninja
|
||||
#subdirs += meson
|
||||
subdirs += findutils
|
||||
subdirs += groff
|
||||
subdirs += gzip
|
||||
|
@ -66,11 +63,10 @@ subdirs += make
|
|||
subdirs += mandoc
|
||||
subdirs += texinfo
|
||||
subdirs += procps-ng
|
||||
subdirs += util-linux
|
||||
# for musl
|
||||
#subdirs += musl-fts
|
||||
subdirs += e2fsprogs
|
||||
#subdirs += haveged
|
||||
subdirs += util-linux
|
||||
subdirs += grep
|
||||
subdirs += sed
|
||||
subdirs += eudev
|
||||
subdirs += skalibs
|
||||
subdirs += execline
|
||||
|
@ -83,6 +79,7 @@ subdirs += bin
|
|||
subdirs += sbin
|
||||
subdirs += usr.bin
|
||||
subdirs += usr.sbin
|
||||
subdirs += ca-certificates
|
||||
|
||||
ifeq ($(arch),x86_64)
|
||||
subdirs += grub
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
distname = acl
|
||||
distext = gz
|
||||
patches += acl-largefile64.patch
|
||||
include world.mk
|
||||
|
||||
config_opts += --host=$(tgt)
|
||||
|
|
12
world/acl/acl-largefile64.patch
Normal file
12
world/acl/acl-largefile64.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
diff -Naur acl-2.3.1/tools/chacl.c acl-2.3.1.orig/tools/chacl.c
|
||||
--- acl-2.3.1/tools/chacl.c 2018-02-28 04:20:39.000000000 -0500
|
||||
+++ acl-2.3.1.orig/tools/chacl.c 2023-08-21 18:33:10.249557883 -0400
|
||||
@@ -17,6 +17,8 @@
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
+#define _LARGEFILE64_SOURCE
|
||||
+
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
|
@ -6,4 +6,9 @@ doinstall = true
|
|||
cflags += -O2
|
||||
cflags += -Wall
|
||||
cflags += --sysroot=$(DESTDIR)
|
||||
|
||||
define post_install
|
||||
install -m644 src/argp.h $(DESTDIR)/usr/include
|
||||
endef
|
||||
|
||||
include hhl.staticlib.mk
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
distname = bc
|
||||
patches += bc-sysroot.patch
|
||||
include world.mk
|
||||
export PREFIX = /usr
|
||||
export CC = $(tgt)-gcc
|
||||
|
|
14
world/bc/bc-sysroot.patch
Normal file
14
world/bc/bc-sysroot.patch
Normal file
|
@ -0,0 +1,14 @@
|
|||
diff -Naur bc-6.0.1.orig/Makefile.in bc-6.0.1/Makefile.in
|
||||
--- bc-6.0.1.orig/Makefile.in 2022-12-28 23:57:08.827199555 -0500
|
||||
+++ bc-6.0.1/Makefile.in 2022-12-28 23:58:23.690714654 -0500
|
||||
@@ -211,8 +211,8 @@
|
||||
CPPFLAGS7 = $(CPPFLAGS6) -D$(BC_ENABLE_EXTRA_MATH_NAME)=$(BC_ENABLE_EXTRA_MATH)
|
||||
CPPFLAGS8 = $(CPPFLAGS7) -DBC_ENABLE_HISTORY=$(BC_ENABLE_HISTORY) -DBC_ENABLE_LIBRARY=$(BC_ENABLE_LIBRARY)
|
||||
CPPFLAGS = $(CPPFLAGS8) -DBC_ENABLE_MEMCHECK=$(BC_ENABLE_MEMCHECK) -DBC_ENABLE_AFL=$(BC_ENABLE_AFL)
|
||||
-CFLAGS = $(CPPFLAGS) $(BC_DEFS) $(DC_DEFS) %%CPPFLAGS%% %%CFLAGS%% -I$(INCLUDEDIR)
|
||||
-LDFLAGS = %%LDFLAGS%% -L$(LIBDIR)
|
||||
+CFLAGS = $(CPPFLAGS) $(BC_DEFS) $(DC_DEFS) %%CPPFLAGS%% %%CFLAGS%% -I$(DESTDIR)$(INCLUDEDIR)
|
||||
+LDFLAGS = %%LDFLAGS%% -L$(DESTDIR)$(LIBDIR)
|
||||
|
||||
HOSTCFLAGS = %%HOSTCFLAGS%%
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
Imported from NetBSD:
|
||||
cat,grep,pwd
|
||||
cat,pwd
|
||||
|
||||
Imported from FreeBSD:
|
||||
ed
|
||||
|
@ -8,6 +8,9 @@ Imported from OpenBSD:
|
|||
chflags,chgrp,chmod,chown,cp,date,dd,df,env,ln,ls,mv,nl,nohup,
|
||||
rm,rmdir,sleep,stty,test,time,touch
|
||||
|
||||
Imported from Sbase:
|
||||
grep
|
||||
|
||||
Imported from MirOS(MirBSD):
|
||||
mksh,lksh,pax
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
See <topsrcsdir>/LICENSE.BSD
|
|
@ -1,17 +0,0 @@
|
|||
# Makefile - hhl - /usr/src/world/cat
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
progname = grep
|
||||
cflags += -Wno-format-nonliteral
|
||||
libs = -lbz2 -lz
|
||||
|
||||
binlinks += ${bindir}/egrep
|
||||
binlinks += ${bindir}/fgrep
|
||||
binlinks += ${bindir}/zgrep
|
||||
binlinks += ${bindir}/zegrep
|
||||
binlinks += ${bindir}/zfgrep
|
||||
|
||||
post_install = for ln in egrep fgrep zgrep zegrep zfgrep ; \
|
||||
do ln -sf grep.1 ${man1dir}/$${ln}.1 ; done
|
||||
|
||||
include hhl.cprog.bsd.mk
|
|
@ -1,486 +0,0 @@
|
|||
.\" $NetBSD: grep.1,v 1.4 2012/04/08 22:00:38 wiz Exp $
|
||||
.\" $FreeBSD: head/usr.bin/grep/grep.1 210652 2010-07-30 14:05:20Z joel $
|
||||
.\" $OpenBSD: grep.1,v 1.38 2010/04/05 06:30:59 jmc Exp $
|
||||
.\" Copyright (c) 1980, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)grep.1 8.3 (Berkeley) 4/18/94
|
||||
.\"
|
||||
.Dd April 19, 2011
|
||||
.Dt GREP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm grep , egrep , fgrep ,
|
||||
.Nm zgrep , zegrep , zfgrep
|
||||
.Nd file pattern searcher
|
||||
.Sh SYNOPSIS
|
||||
.Nm grep
|
||||
.Op Fl abcdDEFGHhIiJLlmnOopqRSsUVvwxZz
|
||||
.Op Fl A Ar num
|
||||
.Op Fl B Ar num
|
||||
.Op Fl C Ns Op Ar num
|
||||
.Op Fl e Ar pattern
|
||||
.Op Fl f Ar file
|
||||
.Op Fl Fl binary-files Ns = Ns Ar value
|
||||
.Op Fl Fl color Ns Op = Ns Ar when
|
||||
.Op Fl Fl colour Ns Op = Ns Ar when
|
||||
.Op Fl Fl context Ns Op = Ns Ar num
|
||||
.Op Fl Fl decompress
|
||||
.Op Fl Fl label
|
||||
.Op Fl Fl line-buffered
|
||||
.Op Ar pattern
|
||||
.Op Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm grep
|
||||
utility searches any given input files,
|
||||
selecting lines that match one or more patterns.
|
||||
By default, a pattern matches an input line if the regular expression
|
||||
(RE) in the pattern matches the input line
|
||||
without its trailing newline.
|
||||
An empty expression matches every line.
|
||||
Each input line that matches at least one of the patterns is written
|
||||
to the standard output.
|
||||
.Pp
|
||||
.Nm grep
|
||||
is used for simple patterns and
|
||||
basic regular expressions
|
||||
.Pq BREs ;
|
||||
.Nm egrep
|
||||
can handle extended regular expressions
|
||||
.Pq EREs .
|
||||
See
|
||||
.Xr re_format 7
|
||||
for more information on regular expressions.
|
||||
.Nm fgrep
|
||||
is quicker than both
|
||||
.Nm grep
|
||||
and
|
||||
.Nm egrep ,
|
||||
but can only handle fixed patterns
|
||||
(i.e. it does not interpret regular expressions).
|
||||
Patterns may consist of one or more lines,
|
||||
allowing any of the pattern lines to match a portion of the input.
|
||||
.Pp
|
||||
.Nm zgrep ,
|
||||
.Nm zegrep ,
|
||||
and
|
||||
.Nm zfgrep
|
||||
act like
|
||||
.Nm grep ,
|
||||
.Nm egrep ,
|
||||
and
|
||||
.Nm fgrep ,
|
||||
respectively, but accept input files compressed with the
|
||||
.Xr compress 1
|
||||
or
|
||||
.Xr gzip 1
|
||||
compression utilities.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl A Ar num , Fl Fl after-context Ns = Ns Ar num
|
||||
Print
|
||||
.Ar num
|
||||
lines of trailing context after each match.
|
||||
See also the
|
||||
.Fl B
|
||||
and
|
||||
.Fl C
|
||||
options.
|
||||
.It Fl a , Fl Fl text
|
||||
Treat all files as ASCII text.
|
||||
Normally
|
||||
.Nm
|
||||
will simply print
|
||||
.Dq Binary file ... matches
|
||||
if files contain binary characters.
|
||||
Use of this option forces
|
||||
.Nm
|
||||
to output lines matching the specified pattern.
|
||||
.It Fl B Ar num , Fl Fl before-context Ns = Ns Ar num
|
||||
Print
|
||||
.Ar num
|
||||
lines of leading context before each match.
|
||||
See also the
|
||||
.Fl A
|
||||
and
|
||||
.Fl C
|
||||
options.
|
||||
.It Fl b , Fl Fl byte-offset
|
||||
The offset in bytes of a matched pattern is
|
||||
displayed in front of the respective matched line.
|
||||
.It Fl C Ns Op Ar num , Fl Fl context Ns = Ns Ar num
|
||||
Print
|
||||
.Ar num
|
||||
lines of leading and trailing context surrounding each match.
|
||||
The default is 2 and is equivalent to
|
||||
.Fl A
|
||||
.Ar 2
|
||||
.Fl B
|
||||
.Ar 2 .
|
||||
Note:
|
||||
no whitespace may be given between the option and its argument.
|
||||
.It Fl c , Fl Fl count
|
||||
Only a count of selected lines is written to standard output.
|
||||
.It Fl Fl colour Ns = Ns Op Ar when , Fl Fl color Ns = Ns Op Ar when
|
||||
Mark up the matching text with the expression stored in
|
||||
.Ev GREP_COLOR
|
||||
environment variable.
|
||||
The possible values of when can be `never', `always' or `auto'.
|
||||
.It Fl D Ar action , Fl Fl devices Ns = Ns Ar action
|
||||
Specify the demanded action for devices, FIFOs and sockets.
|
||||
The default action is `read', which means, that they are read
|
||||
as if they were normal files.
|
||||
If the action is set to `skip', devices will be silently skipped.
|
||||
.It Fl d Ar action , Fl Fl directories Ns = Ns Ar action
|
||||
Specify the demanded action for directories.
|
||||
It is `read' by default, which means that the directories
|
||||
are read in the same manner as normal files.
|
||||
Other possible values are `skip' to silently ignore the
|
||||
directories, and `recurse' to read them recursively, which
|
||||
has the same effect as the
|
||||
.Fl R
|
||||
and
|
||||
.Fl r
|
||||
option.
|
||||
.It Fl E , Fl Fl extended-regexp
|
||||
Interpret
|
||||
.Ar pattern
|
||||
as an extended regular expression
|
||||
(i.e. force
|
||||
.Nm grep
|
||||
to behave as
|
||||
.Nm egrep ) .
|
||||
.It Fl e Ar pattern , Fl Fl regexp Ns = Ns Ar pattern
|
||||
Specify a pattern used during the search of the input:
|
||||
an input line is selected if it matches any of the specified patterns.
|
||||
This option is most useful when multiple
|
||||
.Fl e
|
||||
options are used to specify multiple patterns,
|
||||
or when a pattern begins with a dash
|
||||
.Pq Sq - .
|
||||
.It Fl Fl exclude
|
||||
If specified, it excludes files matching the given
|
||||
filename pattern from the search.
|
||||
Note that
|
||||
.Fl Fl exclude
|
||||
patterns take priority over
|
||||
.Fl Fl include
|
||||
patterns, and if no
|
||||
.Fl Fl include
|
||||
pattern is specified, all files are searched that are
|
||||
not excluded.
|
||||
Patterns are matched to the full path specified,
|
||||
not only to the filename component.
|
||||
.It Fl Fl exclude-dir
|
||||
If
|
||||
.Fl R
|
||||
is specified, it excludes directories matching the
|
||||
given filename pattern from the search.
|
||||
Note that
|
||||
.Fl Fl exclude-dir
|
||||
patterns take priority over
|
||||
.Fl Fl include-dir
|
||||
patterns, and if no
|
||||
.Fl Fl include-dir
|
||||
pattern is specified, all directories are searched that are
|
||||
not excluded.
|
||||
.It Fl F , Fl Fl fixed-strings
|
||||
Interpret
|
||||
.Ar pattern
|
||||
as a set of fixed strings
|
||||
(i.e. force
|
||||
.Nm grep
|
||||
to behave as
|
||||
.Nm fgrep ) .
|
||||
.It Fl f Ar file , Fl Fl file Ns = Ns Ar file
|
||||
Read one or more newline separated patterns from
|
||||
.Ar file .
|
||||
Empty pattern lines match every input line.
|
||||
Newlines are not considered part of a pattern.
|
||||
If
|
||||
.Ar file
|
||||
is empty, nothing is matched.
|
||||
.It Fl G , Fl Fl basic-regexp
|
||||
Interpret
|
||||
.Ar pattern
|
||||
as a basic regular expression
|
||||
(i.e. force
|
||||
.Nm grep
|
||||
to behave as traditional
|
||||
.Nm grep ) .
|
||||
.It Fl H
|
||||
Always print filename headers with output lines.
|
||||
.It Fl h , Fl Fl no-filename
|
||||
Never print filename headers
|
||||
.Pq i.e. filenames
|
||||
with output lines.
|
||||
.It Fl Fl help
|
||||
Print a brief help message.
|
||||
.It Fl I
|
||||
Ignore binary files.
|
||||
This option is equivalent to
|
||||
.Fl Fl binary-file Ns = Ns Ar without-match
|
||||
option.
|
||||
.It Fl i , Fl Fl ignore-case
|
||||
Perform case insensitive matching.
|
||||
By default,
|
||||
.Nm grep
|
||||
is case sensitive.
|
||||
.It Fl Fl include
|
||||
If specified, only files matching the
|
||||
given filename pattern are searched.
|
||||
Note that
|
||||
.Fl Fl exclude
|
||||
patterns take priority over
|
||||
.Fl Fl include
|
||||
patterns.
|
||||
Patterns are matched to the full path specified,
|
||||
not only to the filename component.
|
||||
.It Fl Fl include-dir
|
||||
If
|
||||
.Fl R
|
||||
is specified, only directories matching the
|
||||
given filename pattern are searched.
|
||||
Note that
|
||||
.Fl Fl exclude-dir
|
||||
patterns take priority over
|
||||
.Fl Fl include-dir
|
||||
patterns.
|
||||
.It Fl J, Fl Fl bz2decompress
|
||||
Decompress the
|
||||
.Xr bzip2 1
|
||||
compressed file before looking for the text.
|
||||
.It Fl L , Fl Fl files-without-match
|
||||
Only the names of files not containing selected lines are written to
|
||||
standard output.
|
||||
Pathnames are listed once per file searched.
|
||||
If the standard input is searched, the string
|
||||
.Dq (standard input)
|
||||
is written.
|
||||
.It Fl l , Fl Fl files-with-matches
|
||||
Only the names of files containing selected lines are written to
|
||||
standard output.
|
||||
.Nm grep
|
||||
will only search a file until a match has been found,
|
||||
making searches potentially less expensive.
|
||||
Pathnames are listed once per file searched.
|
||||
If the standard input is searched, the string
|
||||
.Dq (standard input)
|
||||
is written.
|
||||
.It Fl Fl mmap
|
||||
Use
|
||||
.Xr mmap 2
|
||||
instead of
|
||||
.Xr read 2
|
||||
to read input, which can result in better performance under some
|
||||
circumstances but can cause undefined behaviour.
|
||||
.It Fl m Ar num, Fl Fl max-count Ns = Ns Ar num
|
||||
Stop reading the file after
|
||||
.Ar num
|
||||
matches.
|
||||
.It Fl n , Fl Fl line-number
|
||||
Each output line is preceded by its relative line number in the file,
|
||||
starting at line 1.
|
||||
The line number counter is reset for each file processed.
|
||||
This option is ignored if
|
||||
.Fl c ,
|
||||
.Fl L ,
|
||||
.Fl l ,
|
||||
or
|
||||
.Fl q
|
||||
is
|
||||
specified.
|
||||
.It Fl O
|
||||
If
|
||||
.Fl R
|
||||
is specified, follow symbolic links only if they were explicitly listed
|
||||
on the command line.
|
||||
The default is not to follow symbolic links.
|
||||
.It Fl o, Fl Fl only-matching
|
||||
Prints only the matching part of the lines.
|
||||
.It Fl p
|
||||
If
|
||||
.Fl R
|
||||
is specified, no symbolic links are followed.
|
||||
This is the default.
|
||||
.It Fl q , Fl Fl quiet , Fl Fl silent
|
||||
Quiet mode:
|
||||
suppress normal output.
|
||||
.Nm grep
|
||||
will only search a file until a match has been found,
|
||||
making searches potentially less expensive.
|
||||
.It Fl R , Fl r , Fl Fl recursive
|
||||
Recursively search subdirectories listed.
|
||||
.It Fl S
|
||||
If
|
||||
.Fl R
|
||||
is specified, all symbolic links are followed.
|
||||
The default is not to follow symbolic links.
|
||||
.It Fl s , Fl Fl no-messages
|
||||
Silent mode.
|
||||
Nonexistent and unreadable files are ignored
|
||||
(i.e. their error messages are suppressed).
|
||||
.It Fl U , Fl Fl binary
|
||||
Search binary files, but do not attempt to print them.
|
||||
.It Fl V , Fl Fl version
|
||||
Display version information and exit.
|
||||
.It Fl v , Fl Fl invert-match
|
||||
Selected lines are those
|
||||
.Em not
|
||||
matching any of the specified patterns.
|
||||
.It Fl w , Fl Fl word-regexp
|
||||
The expression is searched for as a word (as if surrounded by
|
||||
.Sq [[:<:]]
|
||||
and
|
||||
.Sq [[:>:]] ;
|
||||
see
|
||||
.Xr re_format 7 ) .
|
||||
.It Fl x , Fl Fl line-regexp
|
||||
Only input lines selected against an entire fixed string or regular
|
||||
expression are considered to be matching lines.
|
||||
.It Fl y
|
||||
Equivalent to
|
||||
.Fl i .
|
||||
Obsoleted.
|
||||
.It Fl Z , Fl Fl null
|
||||
Prints a zero-byte after the file name.
|
||||
.It Fl z , Fl Fl null-data
|
||||
Use the zero byte (ASCII NUL) as line separator.
|
||||
.It Fl Fl binary-files Ns = Ns Ar value
|
||||
Controls searching and printing of binary files.
|
||||
Options are
|
||||
.Ar binary ,
|
||||
the default: search binary files but do not print them;
|
||||
.Ar without-match :
|
||||
do not search binary files;
|
||||
and
|
||||
.Ar text :
|
||||
treat all files as text.
|
||||
.It Fl Fl decompress
|
||||
Detect input files compressed with
|
||||
.Xr bzip2 1
|
||||
or
|
||||
.Xr gzip 1
|
||||
and decompress them dynamically.
|
||||
This makes
|
||||
.Nm grep
|
||||
behave like
|
||||
.Nm zgrep .
|
||||
.It Fl Fl line-buffered
|
||||
Force output to be line buffered.
|
||||
By default, output is line buffered when standard output is a terminal
|
||||
and block buffered otherwise.
|
||||
.Pp
|
||||
.El
|
||||
If no file arguments are specified, the standard input is used.
|
||||
.Sh EXIT STATUS
|
||||
The
|
||||
.Nm grep
|
||||
utility exits with one of the following values:
|
||||
.Pp
|
||||
.Bl -tag -width flag -compact
|
||||
.It Li 0
|
||||
One or more lines were selected.
|
||||
.It Li 1
|
||||
No lines were selected.
|
||||
.It Li \*(Gt1
|
||||
An error occurred.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
To find all occurrences of the word
|
||||
.Sq patricia
|
||||
in a file:
|
||||
.Pp
|
||||
.Dl $ grep 'patricia' myfile
|
||||
.Pp
|
||||
To find all occurrences of the pattern
|
||||
.Ql .Pp
|
||||
at the beginning of a line:
|
||||
.Pp
|
||||
.Dl $ grep '^\e.Pp' myfile
|
||||
.Pp
|
||||
The apostrophes ensure the entire expression is evaluated by
|
||||
.Nm grep
|
||||
instead of by the user's shell.
|
||||
The caret
|
||||
.Ql ^
|
||||
matches the null string at the beginning of a line,
|
||||
and the
|
||||
.Ql \e
|
||||
escapes the
|
||||
.Ql \&. ,
|
||||
which would otherwise match any character.
|
||||
.Pp
|
||||
To find all lines in a file which do not contain the words
|
||||
.Sq foo
|
||||
or
|
||||
.Sq bar :
|
||||
.Pp
|
||||
.Dl $ grep -v -e 'foo' -e 'bar' myfile
|
||||
.Pp
|
||||
A simple example of an extended regular expression:
|
||||
.Pp
|
||||
.Dl $ egrep '19|20|25' calendar
|
||||
.Pp
|
||||
Peruses the file
|
||||
.Sq calendar
|
||||
looking for either 19, 20, or 25.
|
||||
.Sh SEE ALSO
|
||||
.Xr ed 1 ,
|
||||
.Xr ex 1 ,
|
||||
.Xr gzip 1 ,
|
||||
.Xr sed 1 ,
|
||||
.Xr re_format 7
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
utility is compliant with the
|
||||
.St -p1003.1-2008
|
||||
specification.
|
||||
.Pp
|
||||
The flags
|
||||
.Op Fl AaBbCDdGHhIJLmoPRSUVwZ
|
||||
are extensions to that specification, and the behaviour of the
|
||||
.Fl f
|
||||
flag when used with an empty pattern file is left undefined.
|
||||
.Pp
|
||||
All long options are provided for compatibility with
|
||||
GNU versions of this utility.
|
||||
.Pp
|
||||
Historic versions of the
|
||||
.Nm grep
|
||||
utility also supported the flags
|
||||
.Op Fl ruy .
|
||||
This implementation supports those options;
|
||||
however, their use is strongly discouraged.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm grep
|
||||
command first appeared in
|
||||
.At v6 .
|
|
@ -1,13 +0,0 @@
|
|||
$ $FreeBSD: head/usr.bin/grep/nls/C.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(standard input)"
|
||||
2 "cannot read bzip2 compressed file"
|
||||
3 "unknown %s option"
|
||||
4 "usage: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A num] [-B num] [-C[num]]\n"
|
||||
5 "\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n"
|
||||
6 "\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n"
|
||||
7 "\t[pattern] [file ...]\n"
|
||||
8 "Binary file %s matches\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: es_ES.ISO8859-1.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/es_ES.ISO8859-1.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(entrada estándar)"
|
||||
2 "no se puede leer el fichero comprimido bzip2"
|
||||
3 "opción desconocida de %s"
|
||||
4 "uso: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A no] [-B no] [-C[no]]\n"
|
||||
5 "\t[-e pauta] [-f fichero] [--binary-files=valor] [--color=cuando]\n"
|
||||
6 "\t[--context[=no]] [--directories=acción] [--label] [--line-buffered]\n"
|
||||
7 "\t[pauta] [fichero ...]\n"
|
||||
8 "fichero binario %s se ajusta\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: gl_ES.ISO8859-1.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/gl_ES.ISO8859-1.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(entrada estándar)"
|
||||
2 "non se pode ler o ficheiro comprimido bzip2"
|
||||
3 "opción descoñecida de %s"
|
||||
4 "uso: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A no] [-B no] [-C[no]]\n"
|
||||
5 "\t[-e pauta] [-f ficheiro] [--binary-files=valor] [--color=cando]\n"
|
||||
6 "\t[--context[=no]] [--directories=acción] [--label] [--line-buffered]\n"
|
||||
7 "\t[pauta] [ficheiro ...]\n"
|
||||
8 "ficheiro binario %s conforma\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: hu_HU.ISO8859-2.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/hu_HU.ISO8859-2.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(szabványos bemenet)"
|
||||
2 "bzip2 tömörített fájl nem olvasható"
|
||||
3 "ismeretlen %s opció"
|
||||
4 "használat: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A szám] [-B szám] [-C[szám]]\n"
|
||||
5 "\t[-e minta] [-f fájl] [--binary-files=érték] [--color=mikor]\n"
|
||||
6 "\t[--context[=szám]] [--directories=művelet] [--label] [--line-buffered]\n"
|
||||
7 "\t[minta] [fájl ...]\n"
|
||||
8 "%s bináris fájl illeszkedik\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: ja_JP.SJIS.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/ja_JP.SJIS.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(標準入力)"
|
||||
2 "bzip2 圧縮ファイルを読み込むことができません"
|
||||
3 "%s オプションの指定値に誤りがあります"
|
||||
4 "使い方: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A 数字] [-B 数字] [-C[数字]]\n"
|
||||
5 "\t[-e パターン] [-f ファイル名] [--binary-files=値] [--color=値]\n"
|
||||
6 "\t[--context[=数字]] [--directories=動作] [--label] [--line-buffered]\n"
|
||||
7 "\t[パターン] [ファイル名 ...]\n"
|
||||
8 "バイナリファイル %s にマッチしました\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: ja_JP.UTF-8.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/ja_JP.UTF-8.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(標準入力)"
|
||||
2 "bzip2 圧縮ファイルを読み込むことができません"
|
||||
3 "%s オプションの指定値に誤りがあります"
|
||||
4 "使い方: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A 数字] [-B 数字] [-C[数字]]\n"
|
||||
5 "\t[-e パターン] [-f ファイル名] [--binary-files=値] [--color=値]\n"
|
||||
6 "\t[--context[=数字]] [--directories=動作] [--label] [--line-buffered]\n"
|
||||
7 "\t[パターン] [ファイル名 ...]\n"
|
||||
8 "バイナリファイル %s にマッチしました\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: ja_JP.eucJP.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/ja_JP.eucJP.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(標準入力)"
|
||||
2 "bzip2 圧縮ファイルを読み込むことができません"
|
||||
3 "%s オプションの指定値に誤りがあります"
|
||||
4 "使い方: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A 数字] [-B 数字] [-C[数字]]\n"
|
||||
5 "\t[-e パターン] [-f ファイル名] [--binary-files=値] [--color=値]\n"
|
||||
6 "\t[--context[=数字]] [--directories=動作] [--label] [--line-buffered]\n"
|
||||
7 "\t[パターン] [ファイル名 ...]\n"
|
||||
8 "バイナリファイル %s にマッチしました\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: pt_BR.ISO8859-1.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/pt_BR.ISO8859-1.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(entrada padrão)"
|
||||
2 "não se posso ler o fichero comprimido bzip2"
|
||||
3 "opcão não conhecida de %s"
|
||||
4 "uso: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A num] [-B num] [-C[num]]\n"
|
||||
5 "\t[-e padrão] [-f arquivo] [--binary-files=valor] [--color=quando]\n"
|
||||
6 "\t[--context[=num]] [--directories=ação] [--label] [--line-buffered]\n"
|
||||
7 "\t[padrão] [arquivo ...]\n"
|
||||
8 "arquivo binário %s casa com o padrão\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: ru_RU.KOI8-R.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/ru_RU.KOI8-R.msg 210622 2010-07-29 18:02:57Z gabor $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(стандартный ввод)"
|
||||
2 "не могу прочитать сжатый в bzip2 файл"
|
||||
3 "неизвестный ключ %s"
|
||||
4 "использование: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A чис] [-B чис] [-C[чис]]\n"
|
||||
5 "\t[-e шаблон] [-f файл] [--binary-files=значение] [--color=когда]\n"
|
||||
6 "\t[--context[=чис]] [--directories=действие] [--label] [--line-buffered]\n"
|
||||
7 "\t[шаблон] [файл ...]\n"
|
||||
8 "двоичный файл %s совпадает\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,13 +0,0 @@
|
|||
$ $NetBSD: uk_UA.UTF-8.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/uk_UA.UTF-8.msg 210927 2010-08-06 10:34:48Z gabor $
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(стандартний ввід)"
|
||||
2 "не можу прочитати стиснутий bzip2 файл"
|
||||
3 "невiдома опція %s"
|
||||
4 "використання: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A чис] [-B чис] [-C[чис]]\n"
|
||||
5 "\t[-e шаблон] [-f файл] [--binary-files=значення] [--color=коли]\n"
|
||||
6 "\t[--context[=чис] [--directories=дія] [--label] [--line-buffered]\n"
|
||||
7 "\t[шаблон] [файл ...]\n"
|
||||
8 "двійковий файл %s співпадає\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,14 +0,0 @@
|
|||
$ $NetBSD: zh_CN.UTF-8.msg,v 1.2 2011/04/18 22:46:48 joerg Exp $
|
||||
$ $FreeBSD: head/usr.bin/grep/nls/zh_CN.UTF-8.msg 212927 2010-09-20 19:42:52Z delphij $
|
||||
$
|
||||
$set 1
|
||||
$quote "
|
||||
1 "(标准输入)"
|
||||
2 "读取 bzip2 压缩文件时出错"
|
||||
3 "选项 %s 无法识别"
|
||||
4 "用法: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A 行数] [-B 行数] [-C[行数]]\n"
|
||||
5 "\t[-e 模式] [-f 文件] [--binary-files=值] [--color=何时]\n"
|
||||
6 "\t[--context[=行数]] [--directories=动作] [--label] [--line-buffered]\n"
|
||||
7 "\t[模式] [文件名 ...]\n"
|
||||
8 "二进制文件 %s 包含模式\n"
|
||||
9 "%s (BSD grep) %s\n"
|
|
@ -1,336 +0,0 @@
|
|||
/* $OpenBSD: util.c,v 1.36 2007/10/02 17:59:18 otto Exp $ */
|
||||
/* $FreeBSD: head/usr.bin/grep/fastgrep.c 211496 2010-08-19 09:28:59Z des $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (C) 2008 Gabor Kovesdan <gabor@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX: This file is a speed up for grep to cover the defects of the
|
||||
* regex library. These optimizations should practically be implemented
|
||||
* there keeping this code clean. This is a future TODO, but for the
|
||||
* meantime, we need to use this workaround.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <bsd/sys/cdefs.h>
|
||||
__RCSID("$NetBSD: fastgrep.c,v 1.5 2011/04/18 03:27:40 joerg Exp $");
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "grep.h"
|
||||
|
||||
static inline int grep_cmp(const unsigned char *, const unsigned char *, size_t);
|
||||
static inline void grep_revstr(unsigned char *, int);
|
||||
|
||||
void
|
||||
fgrepcomp(fastgrep_t *fg, const char *pat)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Initialize. */
|
||||
fg->len = strlen(pat);
|
||||
fg->bol = false;
|
||||
fg->eol = false;
|
||||
fg->reversed = false;
|
||||
|
||||
fg->pattern = (unsigned char *)grep_strdup(pat);
|
||||
|
||||
/* Preprocess pattern. */
|
||||
for (i = 0; i <= UCHAR_MAX; i++)
|
||||
fg->qsBc[i] = fg->len;
|
||||
for (i = 1; i < fg->len; i++)
|
||||
fg->qsBc[fg->pattern[i]] = fg->len - i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: -1 on failure, 0 on success
|
||||
*/
|
||||
int
|
||||
fastcomp(fastgrep_t *fg, const char *pat)
|
||||
{
|
||||
unsigned int i;
|
||||
int firstHalfDot = -1;
|
||||
int firstLastHalfDot = -1;
|
||||
int hasDot = 0;
|
||||
int lastHalfDot = 0;
|
||||
int shiftPatternLen;
|
||||
|
||||
/* Initialize. */
|
||||
fg->len = strlen(pat);
|
||||
fg->bol = false;
|
||||
fg->eol = false;
|
||||
fg->reversed = false;
|
||||
fg->word = wflag;
|
||||
|
||||
/* Remove end-of-line character ('$'). */
|
||||
if (fg->len > 0 && pat[fg->len - 1] == '$') {
|
||||
fg->eol = true;
|
||||
fg->len--;
|
||||
}
|
||||
|
||||
/* Remove beginning-of-line character ('^'). */
|
||||
if (pat[0] == '^') {
|
||||
fg->bol = true;
|
||||
fg->len--;
|
||||
pat++;
|
||||
}
|
||||
|
||||
if (fg->len >= 14 &&
|
||||
memcmp(pat, "[[:<:]]", 7) == 0 &&
|
||||
memcmp(pat + fg->len - 7, "[[:>:]]", 7) == 0) {
|
||||
fg->len -= 14;
|
||||
pat += 7;
|
||||
/* Word boundary is handled separately in util.c */
|
||||
fg->word = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* pat has been adjusted earlier to not include '^', '$' or
|
||||
* the word match character classes at the beginning and ending
|
||||
* of the string respectively.
|
||||
*/
|
||||
fg->pattern = grep_malloc(fg->len + 1);
|
||||
memcpy(fg->pattern, pat, fg->len);
|
||||
fg->pattern[fg->len] = '\0';
|
||||
|
||||
/* Look for ways to cheat...er...avoid the full regex engine. */
|
||||
for (i = 0; i < fg->len; i++) {
|
||||
/* Can still cheat? */
|
||||
if (fg->pattern[i] == '.') {
|
||||
hasDot = i;
|
||||
if (i < fg->len / 2) {
|
||||
if (firstHalfDot < 0)
|
||||
/* Closest dot to the beginning */
|
||||
firstHalfDot = i;
|
||||
} else {
|
||||
/* Closest dot to the end of the pattern. */
|
||||
lastHalfDot = i;
|
||||
if (firstLastHalfDot < 0)
|
||||
firstLastHalfDot = i;
|
||||
}
|
||||
} else {
|
||||
/* Free memory and let others know this is empty. */
|
||||
free(fg->pattern);
|
||||
fg->pattern = NULL;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if a reverse search would be faster based on the placement
|
||||
* of the dots.
|
||||
*/
|
||||
if ((!(lflag || cflag)) && ((!(fg->bol || fg->eol)) &&
|
||||
((lastHalfDot) && ((firstHalfDot < 0) ||
|
||||
((fg->len - (lastHalfDot + 1)) < (size_t)firstHalfDot)))) &&
|
||||
!oflag && !color) {
|
||||
fg->reversed = true;
|
||||
hasDot = fg->len - (firstHalfDot < 0 ?
|
||||
firstLastHalfDot : firstHalfDot) - 1;
|
||||
grep_revstr(fg->pattern, fg->len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Normal Quick Search would require a shift based on the position the
|
||||
* next character after the comparison is within the pattern. With
|
||||
* wildcards, the position of the last dot effects the maximum shift
|
||||
* distance.
|
||||
* The closer to the end the wild card is the slower the search. A
|
||||
* reverse version of this algorithm would be useful for wildcards near
|
||||
* the end of the string.
|
||||
*
|
||||
* Examples:
|
||||
* Pattern Max shift
|
||||
* ------- ---------
|
||||
* this 5
|
||||
* .his 4
|
||||
* t.is 3
|
||||
* th.s 2
|
||||
* thi. 1
|
||||
*/
|
||||
|
||||
/* Adjust the shift based on location of the last dot ('.'). */
|
||||
shiftPatternLen = fg->len - hasDot;
|
||||
|
||||
/* Preprocess pattern. */
|
||||
for (i = 0; i <= (signed)UCHAR_MAX; i++)
|
||||
fg->qsBc[i] = shiftPatternLen;
|
||||
for (i = hasDot + 1; i < fg->len; i++) {
|
||||
fg->qsBc[fg->pattern[i]] = fg->len - i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put pattern back to normal after pre-processing to allow for easy
|
||||
* comparisons later.
|
||||
*/
|
||||
if (fg->reversed)
|
||||
grep_revstr(fg->pattern, fg->len);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
grep_search(fastgrep_t *fg, const unsigned char *data, size_t len, regmatch_t *pmatch)
|
||||
{
|
||||
unsigned int j;
|
||||
int ret = REG_NOMATCH;
|
||||
|
||||
if (pmatch->rm_so == (ssize_t)len)
|
||||
return (ret);
|
||||
|
||||
if (fg->bol && pmatch->rm_so != 0) {
|
||||
pmatch->rm_so = len;
|
||||
pmatch->rm_eo = len;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* No point in going farther if we do not have enough data. */
|
||||
if (len < fg->len)
|
||||
return (ret);
|
||||
|
||||
/* Only try once at the beginning or ending of the line. */
|
||||
if (fg->bol || fg->eol) {
|
||||
/* Simple text comparison. */
|
||||
/* Verify data is >= pattern length before searching on it. */
|
||||
if (len >= fg->len) {
|
||||
/* Determine where in data to start search at. */
|
||||
j = fg->eol ? len - fg->len : 0;
|
||||
if (!((fg->bol && fg->eol) && (len != fg->len)))
|
||||
if (grep_cmp(fg->pattern, data + j,
|
||||
fg->len) == -1) {
|
||||
pmatch->rm_so = j;
|
||||
pmatch->rm_eo = j + fg->len;
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
} else if (fg->reversed) {
|
||||
/* Quick Search algorithm. */
|
||||
j = len;
|
||||
do {
|
||||
if (grep_cmp(fg->pattern, data + j - fg->len,
|
||||
fg->len) == -1) {
|
||||
pmatch->rm_so = j - fg->len;
|
||||
pmatch->rm_eo = j;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
/* Shift if within bounds, otherwise, we are done. */
|
||||
if (j == fg->len)
|
||||
break;
|
||||
j -= fg->qsBc[data[j - fg->len - 1]];
|
||||
} while (j >= fg->len);
|
||||
} else {
|
||||
/* Quick Search algorithm. */
|
||||
j = pmatch->rm_so;
|
||||
do {
|
||||
if (grep_cmp(fg->pattern, data + j, fg->len) == -1) {
|
||||
pmatch->rm_so = j;
|
||||
pmatch->rm_eo = j + fg->len;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Shift if within bounds, otherwise, we are done. */
|
||||
if (j + fg->len == len)
|
||||
break;
|
||||
else
|
||||
j += fg->qsBc[data[j + fg->len]];
|
||||
} while (j <= (len - fg->len));
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns: i >= 0 on failure (position that it failed)
|
||||
* -1 on success
|
||||
*/
|
||||
static inline int
|
||||
grep_cmp(const unsigned char *pat, const unsigned char *data, size_t len)
|
||||
{
|
||||
size_t size;
|
||||
wchar_t *wdata, *wpat;
|
||||
unsigned int i;
|
||||
|
||||
if (iflag) {
|
||||
if ((size = mbstowcs(NULL, (const char *)data, 0)) ==
|
||||
((size_t) - 1))
|
||||
return (-1);
|
||||
|
||||
wdata = grep_malloc(size * sizeof(wint_t));
|
||||
|
||||
if (mbstowcs(wdata, (const char *)data, size) ==
|
||||
((size_t) - 1))
|
||||
return (-1);
|
||||
|
||||
if ((size = mbstowcs(NULL, (const char *)pat, 0)) ==
|
||||
((size_t) - 1))
|
||||
return (-1);
|
||||
|
||||
wpat = grep_malloc(size * sizeof(wint_t));
|
||||
|
||||
if (mbstowcs(wpat, (const char *)pat, size) == ((size_t) - 1))
|
||||
return (-1);
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((towlower(wpat[i]) == towlower(wdata[i])) ||
|
||||
((grepbehave != GREP_FIXED) && wpat[i] == L'.'))
|
||||
continue;
|
||||
free(wpat);
|
||||
free(wdata);
|
||||
return (i);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((pat[i] == data[i]) || ((grepbehave != GREP_FIXED) &&
|
||||
pat[i] == '.'))
|
||||
continue;
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static inline void
|
||||
grep_revstr(unsigned char *str, int len)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
for (i = 0; i < len / 2; i++) {
|
||||
c = str[i];
|
||||
str[i] = str[len - i - 1];
|
||||
str[len - i - 1] = c;
|
||||
}
|
||||
}
|
|
@ -1,279 +0,0 @@
|
|||
/* $NetBSD: file.c,v 1.11 2019/04/05 13:34:41 christos Exp $ */
|
||||
/* $FreeBSD: head/usr.bin/grep/file.c 211496 2010-08-19 09:28:59Z des $ */
|
||||
/* $OpenBSD: file.c,v 1.11 2010/07/02 20:48:48 nicm Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
|
||||
* Copyright (C) 2010 Dimitry Andric <dimitry@andric.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <bsd/sys/cdefs.h>
|
||||
__RCSID("$NetBSD: file.c,v 1.11 2019/04/05 13:34:41 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "grep.h"
|
||||
|
||||
#define MAXBUFSIZ (32 * 1024)
|
||||
#define LNBUFBUMP 80
|
||||
|
||||
#ifndef WITHOUT_GZIP
|
||||
static gzFile gzbufdesc;
|
||||
#endif
|
||||
#ifndef WITHOUT_BZ2
|
||||
static BZFILE* bzbufdesc;
|
||||
#endif
|
||||
|
||||
static unsigned char buffer[MAXBUFSIZ + 1];
|
||||
static unsigned char *bufpos;
|
||||
static size_t bufrem;
|
||||
|
||||
static unsigned char *lnbuf;
|
||||
static size_t lnbuflen;
|
||||
|
||||
static inline int
|
||||
grep_refill(struct file *f)
|
||||
{
|
||||
ssize_t nr = -1;
|
||||
int bzerr;
|
||||
|
||||
bufpos = buffer;
|
||||
bufrem = 0;
|
||||
|
||||
#ifndef WITHOUT_GZIP
|
||||
if (filebehave == FILE_GZIP) {
|
||||
nr = gzread(gzbufdesc, buffer, MAXBUFSIZ);
|
||||
if (nr == -1)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifndef WITHOUT_BZ2
|
||||
if (filebehave == FILE_BZIP && bzbufdesc != NULL) {
|
||||
nr = BZ2_bzRead(&bzerr, bzbufdesc, buffer, MAXBUFSIZ);
|
||||
switch (bzerr) {
|
||||
case BZ_OK:
|
||||
case BZ_STREAM_END:
|
||||
/* No problem, nr will be okay */
|
||||
break;
|
||||
case BZ_DATA_ERROR_MAGIC:
|
||||
/*
|
||||
* As opposed to gzread(), which simply returns the
|
||||
* plain file data, if it is not in the correct
|
||||
* compressed format, BZ2_bzRead() instead aborts.
|
||||
*
|
||||
* So, just restart at the beginning of the file again,
|
||||
* and use plain reads from now on.
|
||||
*/
|
||||
BZ2_bzReadClose(&bzerr, bzbufdesc);
|
||||
bzbufdesc = NULL;
|
||||
if (lseek(f->fd, 0, SEEK_SET) == -1)
|
||||
return (-1);
|
||||
nr = read(f->fd, buffer, MAXBUFSIZ);
|
||||
break;
|
||||
default:
|
||||
/* Make sure we exit with an error */
|
||||
nr = -1;
|
||||
}
|
||||
if (nr == -1)
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if (nr == -1) {
|
||||
nr = read(f->fd, buffer, MAXBUFSIZ);
|
||||
}
|
||||
|
||||
if (nr < 0)
|
||||
return (-1);
|
||||
|
||||
bufrem = nr;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline void
|
||||
grep_lnbufgrow(size_t newlen)
|
||||
{
|
||||
|
||||
if (lnbuflen < newlen) {
|
||||
lnbuf = grep_realloc(lnbuf, newlen);
|
||||
lnbuflen = newlen;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grep_copyline(size_t off, size_t len)
|
||||
{
|
||||
memcpy(lnbuf + off, bufpos, len);
|
||||
lnbuf[off + len] = '\0';
|
||||
}
|
||||
|
||||
char *
|
||||
grep_fgetln(struct file *f, size_t *lenp)
|
||||
{
|
||||
unsigned char *p;
|
||||
size_t len;
|
||||
size_t off;
|
||||
ptrdiff_t diff;
|
||||
|
||||
/* Fill the buffer, if necessary */
|
||||
if (bufrem == 0 && grep_refill(f) != 0)
|
||||
goto error;
|
||||
|
||||
if (bufrem == 0) {
|
||||
/* Return zero length to indicate EOF */
|
||||
*lenp = 0;
|
||||
return ((char *)bufpos);
|
||||
}
|
||||
|
||||
/* Look for a newline in the remaining part of the buffer */
|
||||
if ((p = memchr(bufpos, line_sep, bufrem)) != NULL) {
|
||||
++p; /* advance over newline */
|
||||
len = p - bufpos;
|
||||
grep_lnbufgrow(len + 1);
|
||||
grep_copyline(0, len);
|
||||
*lenp = len;
|
||||
bufrem -= len;
|
||||
bufpos = p;
|
||||
return (char *)lnbuf;
|
||||
}
|
||||
|
||||
/* We have to copy the current buffered data to the line buffer */
|
||||
for (len = bufrem, off = 0; ; len += bufrem) {
|
||||
/* Make sure there is room for more data */
|
||||
grep_lnbufgrow(len + LNBUFBUMP);
|
||||
grep_copyline(off, len - off);
|
||||
off = len;
|
||||
if (grep_refill(f) != 0)
|
||||
goto error;
|
||||
if (bufrem == 0)
|
||||
/* EOF: return partial line */
|
||||
break;
|
||||
if ((p = memchr(bufpos, line_sep, bufrem)) == NULL)
|
||||
continue;
|
||||
/* got it: finish up the line (like code above) */
|
||||
++p;
|
||||
diff = p - bufpos;
|
||||
len += diff;
|
||||
grep_lnbufgrow(len + 1);
|
||||
grep_copyline(off, diff);
|
||||
bufrem -= diff;
|
||||
bufpos = p;
|
||||
break;
|
||||
}
|
||||
*lenp = len;
|
||||
return ((char *)lnbuf);
|
||||
|
||||
error:
|
||||
*lenp = 0;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static inline struct file *
|
||||
grep_file_init(struct file *f)
|
||||
{
|
||||
|
||||
#ifndef WITHOUT_GZIP
|
||||
if (filebehave == FILE_GZIP &&
|
||||
(gzbufdesc = gzdopen(f->fd, "r")) == NULL)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#ifndef WITHOUT_BZ2
|
||||
if (filebehave == FILE_BZIP &&
|
||||
(bzbufdesc = BZ2_bzdopen(f->fd, "r")) == NULL)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
/* Fill read buffer, also catches errors early */
|
||||
if (grep_refill(f) != 0)
|
||||
goto error;
|
||||
|
||||
/* Check for binary stuff, if necessary */
|
||||
if (!nulldataflag && binbehave != BINFILE_TEXT &&
|
||||
memchr(bufpos, '\0', bufrem) != NULL)
|
||||
f->binary = true;
|
||||
|
||||
return (f);
|
||||
error:
|
||||
close(f->fd);
|
||||
free(f);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a file for processing.
|
||||
*/
|
||||
struct file *
|
||||
grep_open(const char *path)
|
||||
{
|
||||
struct file *f;
|
||||
|
||||
f = grep_malloc(sizeof *f);
|
||||
memset(f, 0, sizeof *f);
|
||||
if (path == NULL) {
|
||||
/* Processing stdin implies --line-buffered. */
|
||||
lbflag = true;
|
||||
f->fd = STDIN_FILENO;
|
||||
} else if ((f->fd = open(path, O_RDONLY)) == -1) {
|
||||
free(f);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (grep_file_init(f));
|
||||
}
|
||||
|
||||
/*
|
||||
* Closes a file.
|
||||
*/
|
||||
void
|
||||
grep_close(struct file *f)
|
||||
{
|
||||
|
||||
close(f->fd);
|
||||
|
||||
/* Reset read buffer and line buffer */
|
||||
bufpos = buffer;
|
||||
bufrem = 0;
|
||||
|
||||
free(lnbuf);
|
||||
lnbuf = NULL;
|
||||
lnbuflen = 0;
|
||||
}
|
|
@ -1,723 +0,0 @@
|
|||
/* $NetBSD: grep.c,v 1.15 2018/08/12 09:03:21 christos Exp $ */
|
||||
/* $FreeBSD: head/usr.bin/grep/grep.c 211519 2010-08-19 22:55:17Z delphij $ */
|
||||
/* $OpenBSD: grep.c,v 1.42 2010/07/02 22:18:03 tedu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <bsd/sys/cdefs.h>
|
||||
__RCSID("$NetBSD: grep.c,v 1.15 2018/08/12 09:03:21 christos Exp $");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <limits.h>
|
||||
#include <libgen.h>
|
||||
#include <locale.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <bsd/compat.h>
|
||||
#include "grep.h"
|
||||
|
||||
#ifndef WITHOUT_NLS
|
||||
#include <nl_types.h>
|
||||
nl_catd catalog;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Default messags to use when NLS is disabled or no catalogue
|
||||
* is found.
|
||||
*/
|
||||
const char *errstr[] = {
|
||||
"",
|
||||
/* 1*/ "(standard input)",
|
||||
/* 2*/ "cannot read bzip2 compressed file",
|
||||
/* 3*/ "unknown %s option",
|
||||
/* 4*/ "usage: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A num] [-B num] [-C[num]]\n",
|
||||
/* 5*/ "\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n",
|
||||
/* 6*/ "\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n",
|
||||
/* 7*/ "\t[pattern] [file ...]\n",
|
||||
/* 8*/ "Binary file %s matches\n",
|
||||
/* 9*/ "%s (BSD grep) %s\n",
|
||||
};
|
||||
|
||||
/* Flags passed to regcomp() and regexec() */
|
||||
int cflags = 0;
|
||||
int eflags = REG_STARTEND;
|
||||
|
||||
/* Searching patterns */
|
||||
unsigned int patterns, pattern_sz;
|
||||
char **pattern;
|
||||
regex_t *r_pattern;
|
||||
fastgrep_t *fg_pattern;
|
||||
|
||||
/* Filename exclusion/inclusion patterns */
|
||||
unsigned int fpatterns, fpattern_sz;
|
||||
unsigned int dpatterns, dpattern_sz;
|
||||
struct epat *dpattern, *fpattern;
|
||||
|
||||
/* For regex errors */
|
||||
char re_error[RE_ERROR_BUF + 1];
|
||||
|
||||
/* Command-line flags */
|
||||
unsigned long long Aflag; /* -A x: print x lines trailing each match */
|
||||
unsigned long long Bflag; /* -B x: print x lines leading each match */
|
||||
bool Hflag; /* -H: always print file name */
|
||||
bool Lflag; /* -L: only show names of files with no matches */
|
||||
bool bflag; /* -b: show block numbers for each match */
|
||||
bool cflag; /* -c: only show a count of matching lines */
|
||||
bool hflag; /* -h: don't print filename headers */
|
||||
bool iflag; /* -i: ignore case */
|
||||
bool lflag; /* -l: only show names of files with matches */
|
||||
bool mflag; /* -m x: stop reading the files after x matches */
|
||||
unsigned long long mcount; /* count for -m */
|
||||
bool nflag; /* -n: show line numbers in front of matching lines */
|
||||
bool oflag; /* -o: print only matching part */
|
||||
bool qflag; /* -q: quiet mode (don't output anything) */
|
||||
bool sflag; /* -s: silent mode (ignore errors) */
|
||||
bool vflag; /* -v: only show non-matching lines */
|
||||
bool wflag; /* -w: pattern must start and end on word boundaries */
|
||||
bool xflag; /* -x: pattern must match entire line */
|
||||
bool lbflag; /* --line-buffered */
|
||||
bool nullflag; /* --null */
|
||||
bool nulldataflag; /* --null-data */
|
||||
unsigned char line_sep = '\n'; /* 0 for --null-data */
|
||||
char *label; /* --label */
|
||||
const char *color; /* --color */
|
||||
int grepbehave = GREP_BASIC; /* -EFGP: type of the regex */
|
||||
int binbehave = BINFILE_BIN; /* -aIU: handling of binary files */
|
||||
int filebehave = FILE_STDIO; /* -JZ: normal, gzip or bzip2 file */
|
||||
int devbehave = DEV_READ; /* -D: handling of devices */
|
||||
int dirbehave = DIR_READ; /* -dRr: handling of directories */
|
||||
int linkbehave = LINK_READ; /* -OpS: handling of symlinks */
|
||||
|
||||
bool dexclude, dinclude; /* --exclude-dir and --include-dir */
|
||||
bool fexclude, finclude; /* --exclude and --include */
|
||||
|
||||
enum {
|
||||
BIN_OPT = CHAR_MAX + 1,
|
||||
COLOR_OPT,
|
||||
DECOMPRESS_OPT,
|
||||
HELP_OPT,
|
||||
MMAP_OPT,
|
||||
LINEBUF_OPT,
|
||||
LABEL_OPT,
|
||||
R_EXCLUDE_OPT,
|
||||
R_INCLUDE_OPT,
|
||||
R_DEXCLUDE_OPT,
|
||||
R_DINCLUDE_OPT
|
||||
};
|
||||
|
||||
static inline const char *init_color(const char *);
|
||||
|
||||
/* Housekeeping */
|
||||
int tail; /* lines left to print */
|
||||
bool notfound; /* file not found */
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
/*
|
||||
* Prints usage information and returns 2.
|
||||
*/
|
||||
__dead static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, getstr(4), __progname);
|
||||
fprintf(stderr, "%s", getstr(5));
|
||||
fprintf(stderr, "%s", getstr(6));
|
||||
fprintf(stderr, "%s", getstr(7));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
static const char optstr[] =
|
||||
"0123456789A:B:C:D:EFGHIJLOPSRUVZabcd:e:f:hilm:nopqrsuvwxyz";
|
||||
|
||||
struct option long_options[] =
|
||||
{
|
||||
{"binary-files", required_argument, NULL, BIN_OPT},
|
||||
#ifndef WITHOUT_GZIP
|
||||
{"decompress", no_argument, NULL, DECOMPRESS_OPT},
|
||||
#endif
|
||||
{"help", no_argument, NULL, HELP_OPT},
|
||||
{"mmap", no_argument, NULL, MMAP_OPT},
|
||||
{"line-buffered", no_argument, NULL, LINEBUF_OPT},
|
||||
{"label", required_argument, NULL, LABEL_OPT},
|
||||
{"color", optional_argument, NULL, COLOR_OPT},
|
||||
{"colour", optional_argument, NULL, COLOR_OPT},
|
||||
{"exclude", required_argument, NULL, R_EXCLUDE_OPT},
|
||||
{"include", required_argument, NULL, R_INCLUDE_OPT},
|
||||
{"exclude-dir", required_argument, NULL, R_DEXCLUDE_OPT},
|
||||
{"include-dir", required_argument, NULL, R_DINCLUDE_OPT},
|
||||
{"after-context", required_argument, NULL, 'A'},
|
||||
{"text", no_argument, NULL, 'a'},
|
||||
{"before-context", required_argument, NULL, 'B'},
|
||||
{"byte-offset", no_argument, NULL, 'b'},
|
||||
{"context", optional_argument, NULL, 'C'},
|
||||
{"count", no_argument, NULL, 'c'},
|
||||
{"devices", required_argument, NULL, 'D'},
|
||||
{"directories", required_argument, NULL, 'd'},
|
||||
{"extended-regexp", no_argument, NULL, 'E'},
|
||||
{"regexp", required_argument, NULL, 'e'},
|
||||
{"fixed-strings", no_argument, NULL, 'F'},
|
||||
{"file", required_argument, NULL, 'f'},
|
||||
{"basic-regexp", no_argument, NULL, 'G'},
|
||||
{"no-filename", no_argument, NULL, 'h'},
|
||||
{"with-filename", no_argument, NULL, 'H'},
|
||||
{"ignore-case", no_argument, NULL, 'i'},
|
||||
#ifndef WITHOUT_BZ2
|
||||
{"bz2decompress", no_argument, NULL, 'J'},
|
||||
#endif
|
||||
{"files-with-matches", no_argument, NULL, 'l'},
|
||||
{"files-without-match", no_argument, NULL, 'L'},
|
||||
{"max-count", required_argument, NULL, 'm'},
|
||||
{"line-number", no_argument, NULL, 'n'},
|
||||
{"only-matching", no_argument, NULL, 'o'},
|
||||
{"quiet", no_argument, NULL, 'q'},
|
||||
{"silent", no_argument, NULL, 'q'},
|
||||
{"recursive", no_argument, NULL, 'r'},
|
||||
{"no-messages", no_argument, NULL, 's'},
|
||||
{"binary", no_argument, NULL, 'U'},
|
||||
{"unix-byte-offsets", no_argument, NULL, 'u'},
|
||||
{"invert-match", no_argument, NULL, 'v'},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"word-regexp", no_argument, NULL, 'w'},
|
||||
{"line-regexp", no_argument, NULL, 'x'},
|
||||
{"null", no_argument, NULL, 'Z'},
|
||||
{"null-data", no_argument, NULL, 'z'},
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Adds a searching pattern to the internal array.
|
||||
*/
|
||||
static void
|
||||
add_pattern(char *pat, size_t len)
|
||||
{
|
||||
|
||||
/* TODO: Check for empty patterns and shortcut */
|
||||
|
||||
/* Increase size if necessary */
|
||||
if (patterns == pattern_sz) {
|
||||
pattern_sz *= 2;
|
||||
pattern = grep_realloc(pattern, ++pattern_sz *
|
||||
sizeof(*pattern));
|
||||
}
|
||||
if (len > 0 && pat[len - 1] == '\n')
|
||||
--len;
|
||||
/* pat may not be NUL-terminated */
|
||||
pattern[patterns] = grep_malloc(len + 1);
|
||||
memcpy(pattern[patterns], pat, len);
|
||||
pattern[patterns][len] = '\0';
|
||||
++patterns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a file include/exclude pattern to the internal array.
|
||||
*/
|
||||
static void
|
||||
add_fpattern(const char *pat, int mode)
|
||||
{
|
||||
|
||||
/* Increase size if necessary */
|
||||
if (fpatterns == fpattern_sz) {
|
||||
fpattern_sz *= 2;
|
||||
fpattern = grep_realloc(fpattern, ++fpattern_sz *
|
||||
sizeof(struct epat));
|
||||
}
|
||||
fpattern[fpatterns].pat = grep_strdup(pat);
|
||||
fpattern[fpatterns].mode = mode;
|
||||
++fpatterns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds a directory include/exclude pattern to the internal array.
|
||||
*/
|
||||
static void
|
||||
add_dpattern(const char *pat, int mode)
|
||||
{
|
||||
|
||||
/* Increase size if necessary */
|
||||
if (dpatterns == dpattern_sz) {
|
||||
dpattern_sz *= 2;
|
||||
dpattern = grep_realloc(dpattern, ++dpattern_sz *
|
||||
sizeof(struct epat));
|
||||
}
|
||||
dpattern[dpatterns].pat = grep_strdup(pat);
|
||||
dpattern[dpatterns].mode = mode;
|
||||
++dpatterns;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads searching patterns from a file and adds them with add_pattern().
|
||||
*/
|
||||
static void
|
||||
read_patterns(const char *fn)
|
||||
{
|
||||
FILE *f;
|
||||
char *line;
|
||||
size_t len;
|
||||
ssize_t rlen;
|
||||
|
||||
if ((f = fopen(fn, "r")) == NULL)
|
||||
err(2, "%s", fn);
|
||||
line = NULL;
|
||||
len = 0;
|
||||
while ((rlen = getline(&line, &len, f)) != -1)
|
||||
add_pattern(line, *line == '\n' ? 0 : (size_t)rlen);
|
||||
free(line);
|
||||
if (ferror(f))
|
||||
err(2, "%s", fn);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
init_color(const char *d)
|
||||
{
|
||||
char *c;
|
||||
|
||||
c = getenv("GREP_COLOR");
|
||||
return (c != NULL ? c : d);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char **aargv, **eargv, *eopts;
|
||||
char *ep;
|
||||
unsigned long long l;
|
||||
unsigned int aargc, eargc, i, j;
|
||||
int c, lastc, needpattern, newarg, prevoptind;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
#ifndef WITHOUT_NLS
|
||||
catalog = catopen("grep", NL_CAT_LOCALE);
|
||||
#endif
|
||||
|
||||
/* Check what is the program name of the binary. In this
|
||||
way we can have all the funcionalities in one binary
|
||||
without the need of scripting and using ugly hacks. */
|
||||
switch (__progname[0]) {
|
||||
case 'e':
|
||||
grepbehave = GREP_EXTENDED;
|
||||
break;
|
||||
case 'f':
|
||||
grepbehave = GREP_FIXED;
|
||||
break;
|
||||
case 'g':
|
||||
grepbehave = GREP_BASIC;
|
||||
break;
|
||||
#ifndef WITHOUT_GZIP
|
||||
case 'z':
|
||||
filebehave = FILE_GZIP;
|
||||
switch(__progname[1]) {
|
||||
case 'e':
|
||||
grepbehave = GREP_EXTENDED;
|
||||
break;
|
||||
case 'f':
|
||||
grepbehave = GREP_FIXED;
|
||||
break;
|
||||
case 'g':
|
||||
grepbehave = GREP_BASIC;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
lastc = '\0';
|
||||
newarg = 1;
|
||||
prevoptind = 1;
|
||||
needpattern = 1;
|
||||
|
||||
eopts = getenv("GREP_OPTIONS");
|
||||
|
||||
/* support for extra arguments in GREP_OPTIONS */
|
||||
eargc = 0;
|
||||
if (eopts != NULL) {
|
||||
char *str;
|
||||
|
||||
/* make an estimation of how many extra arguments we have */
|
||||
for (j = 0; j < strlen(eopts); j++)
|
||||
if (eopts[j] == ' ')
|
||||
eargc++;
|
||||
|
||||
eargv = (char **)grep_malloc(sizeof(char *) * (eargc + 1));
|
||||
|
||||
eargc = 0;
|
||||
/* parse extra arguments */
|
||||
while ((str = strsep(&eopts, " ")) != NULL)
|
||||
eargv[eargc++] = grep_strdup(str);
|
||||
|
||||
aargv = (char **)grep_calloc(eargc + argc + 1,
|
||||
sizeof(char *));
|
||||
|
||||
aargv[0] = argv[0];
|
||||
for (i = 0; i < eargc; i++)
|
||||
aargv[i + 1] = eargv[i];
|
||||
for (j = 1; j < (unsigned int)argc; j++, i++)
|
||||
aargv[i + 1] = argv[j];
|
||||
|
||||
aargc = eargc + argc;
|
||||
} else {
|
||||
aargv = argv;
|
||||
aargc = argc;
|
||||
}
|
||||
|
||||
while (((c = getopt_long(aargc, aargv, optstr, long_options, NULL)) !=
|
||||
-1)) {
|
||||
switch (c) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
if (newarg || !isdigit(lastc))
|
||||
Aflag = 0;
|
||||
else if (Aflag > LLONG_MAX / 10) {
|
||||
errno = ERANGE;
|
||||
err(2, NULL);
|
||||
}
|
||||
Aflag = Bflag = (Aflag * 10) + (c - '0');
|
||||
break;
|
||||
case 'C':
|
||||
if (optarg == NULL) {
|
||||
Aflag = Bflag = 2;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case 'A':
|
||||
/* FALLTHROUGH */
|
||||
case 'B':
|
||||
errno = 0;
|
||||
l = strtoull(optarg, &ep, 10);
|
||||
if (((errno == ERANGE) && (l == ULLONG_MAX)) ||
|
||||
((errno == EINVAL) && (l == 0)))
|
||||
err(2, NULL);
|
||||
else if (ep[0] != '\0') {
|
||||
errno = EINVAL;
|
||||
err(2, NULL);
|
||||
}
|
||||
if (c == 'A')
|
||||
Aflag = l;
|
||||
else if (c == 'B')
|
||||
Bflag = l;
|
||||
else
|
||||
Aflag = Bflag = l;
|
||||
break;
|
||||
case 'a':
|
||||
binbehave = BINFILE_TEXT;
|
||||
break;
|
||||
case 'b':
|
||||
bflag = true;
|
||||
break;
|
||||
case 'c':
|
||||
cflag = true;
|
||||
break;
|
||||
case 'D':
|
||||
if (strcasecmp(optarg, "skip") == 0)
|
||||
devbehave = DEV_SKIP;
|
||||
else if (strcasecmp(optarg, "read") == 0)
|
||||
devbehave = DEV_READ;
|
||||
else
|
||||
errx(2, getstr(3), "--devices");
|
||||
break;
|
||||
case 'd':
|
||||
if (strcasecmp("recurse", optarg) == 0) {
|
||||
Hflag = true;
|
||||
dirbehave = DIR_RECURSE;
|
||||
} else if (strcasecmp("skip", optarg) == 0)
|
||||
dirbehave = DIR_SKIP;
|
||||
else if (strcasecmp("read", optarg) == 0)
|
||||
dirbehave = DIR_READ;
|
||||
else
|
||||
errx(2, getstr(3), "--directories");
|
||||
break;
|
||||
case 'E':
|
||||
grepbehave = GREP_EXTENDED;
|
||||
break;
|
||||
case 'e':
|
||||
add_pattern(optarg, strlen(optarg));
|
||||
needpattern = 0;
|
||||
break;
|
||||
case 'F':
|
||||
grepbehave = GREP_FIXED;
|
||||
break;
|
||||
case 'f':
|
||||
read_patterns(optarg);
|
||||
needpattern = 0;
|
||||
break;
|
||||
case 'G':
|
||||
grepbehave = GREP_BASIC;
|
||||
break;
|
||||
case 'H':
|
||||
Hflag = true;
|
||||
break;
|
||||
case 'h':
|
||||
Hflag = false;
|
||||
hflag = true;
|
||||
break;
|
||||
case 'I':
|
||||
binbehave = BINFILE_SKIP;
|
||||
break;
|
||||
case 'i':
|
||||
case 'y':
|
||||
iflag = true;
|
||||
cflags |= REG_ICASE;
|
||||
break;
|
||||
#ifndef WITHOUT_BZ2
|
||||
case 'J':
|
||||
filebehave = FILE_BZIP;
|
||||
break;
|
||||
#endif
|
||||
case 'L':
|
||||
lflag = false;
|
||||
Lflag = true;
|
||||
break;
|
||||
case 'l':
|
||||
Lflag = false;
|
||||
lflag = true;
|
||||
break;
|
||||
case 'm':
|
||||
mflag = true;
|
||||
errno = 0;
|
||||
mcount = strtoull(optarg, &ep, 10);
|
||||
if (((errno == ERANGE) && (mcount == ULLONG_MAX)) ||
|
||||
((errno == EINVAL) && (mcount == 0)))
|
||||
err(2, NULL);
|
||||
else if (ep[0] != '\0') {
|
||||
errno = EINVAL;
|
||||
err(2, NULL);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
nflag = true;
|
||||
break;
|
||||
case 'O':
|
||||
linkbehave = LINK_EXPLICIT;
|
||||
break;
|
||||
case 'o':
|
||||
oflag = true;
|
||||
break;
|
||||
case 'p':
|
||||
linkbehave = LINK_SKIP;
|
||||
break;
|
||||
case 'q':
|
||||
qflag = true;
|
||||
break;
|
||||
case 'S':
|
||||
linkbehave = LINK_READ;
|
||||
break;
|
||||
case 'R':
|
||||
case 'r':
|
||||
dirbehave = DIR_RECURSE;
|
||||
Hflag = true;
|
||||
break;
|
||||
case 's':
|
||||
sflag = true;
|
||||
break;
|
||||
case 'U':
|
||||
binbehave = BINFILE_BIN;
|
||||
break;
|
||||
case 'u':
|
||||
case MMAP_OPT:
|
||||
/* noop, compatibility */
|
||||
break;
|
||||
case 'V':
|
||||
printf(getstr(9), __progname, VERSION);
|
||||
exit(0);
|
||||
case 'v':
|
||||
vflag = true;
|
||||
break;
|
||||
case 'w':
|
||||
wflag = true;
|
||||
break;
|
||||
case 'x':
|
||||
xflag = true;
|
||||
break;
|
||||
case 'Z':
|
||||
nullflag = true;
|
||||
break;
|
||||
case 'z':
|
||||
nulldataflag = true;
|
||||
line_sep = '\0';
|
||||
break;
|
||||
case BIN_OPT:
|
||||
if (strcasecmp("binary", optarg) == 0)
|
||||
binbehave = BINFILE_BIN;
|
||||
else if (strcasecmp("without-match", optarg) == 0)
|
||||
binbehave = BINFILE_SKIP;
|
||||
else if (strcasecmp("text", optarg) == 0)
|
||||
binbehave = BINFILE_TEXT;
|
||||
else
|
||||
errx(2, getstr(3), "--binary-files");
|
||||
break;
|
||||
case COLOR_OPT:
|
||||
color = NULL;
|
||||
if (optarg == NULL || strcasecmp("auto", optarg) == 0 ||
|
||||
strcasecmp("tty", optarg) == 0 ||
|
||||
strcasecmp("if-tty", optarg) == 0) {
|
||||
char *term;
|
||||
|
||||
term = getenv("TERM");
|
||||
if (isatty(STDOUT_FILENO) && term != NULL &&
|
||||
strcasecmp(term, "dumb") != 0)
|
||||
color = init_color("01;31");
|
||||
} else if (strcasecmp("always", optarg) == 0 ||
|
||||
strcasecmp("yes", optarg) == 0 ||
|
||||
strcasecmp("force", optarg) == 0) {
|
||||
color = init_color("01;31");
|
||||
} else if (strcasecmp("never", optarg) != 0 &&
|
||||
strcasecmp("none", optarg) != 0 &&
|
||||
strcasecmp("no", optarg) != 0)
|
||||
errx(2, getstr(3), "--color");
|
||||
break;
|
||||
#ifndef WITHOUT_GZIP
|
||||
case DECOMPRESS_OPT:
|
||||
filebehave = FILE_GZIP;
|
||||
break;
|
||||
#endif
|
||||
case LABEL_OPT:
|
||||
label = optarg;
|
||||
break;
|
||||
case LINEBUF_OPT:
|
||||
lbflag = true;
|
||||
break;
|
||||
case R_INCLUDE_OPT:
|
||||
finclude = true;
|
||||
add_fpattern(optarg, INCL_PAT);
|
||||
break;
|
||||
case R_EXCLUDE_OPT:
|
||||
fexclude = true;
|
||||
add_fpattern(optarg, EXCL_PAT);
|
||||
break;
|
||||
case R_DINCLUDE_OPT:
|
||||
dinclude = true;
|
||||
add_dpattern(optarg, INCL_PAT);
|
||||
break;
|
||||
case R_DEXCLUDE_OPT:
|
||||
dexclude = true;
|
||||
add_dpattern(optarg, EXCL_PAT);
|
||||
break;
|
||||
case HELP_OPT:
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
lastc = c;
|
||||
newarg = optind != prevoptind;
|
||||
prevoptind = optind;
|
||||
}
|
||||
aargc -= optind;
|
||||
aargv += optind;
|
||||
|
||||
/* Fail if we don't have any pattern */
|
||||
if (aargc == 0 && needpattern)
|
||||
usage();
|
||||
|
||||
/* Process patterns from command line */
|
||||
if (aargc != 0 && needpattern) {
|
||||
add_pattern(*aargv, strlen(*aargv));
|
||||
--aargc;
|
||||
++aargv;
|
||||
}
|
||||
|
||||
switch (grepbehave) {
|
||||
case GREP_FIXED:
|
||||
case GREP_BASIC:
|
||||
break;
|
||||
case GREP_EXTENDED:
|
||||
cflags |= REG_EXTENDED;
|
||||
break;
|
||||
default:
|
||||
/* NOTREACHED */
|
||||
usage();
|
||||
}
|
||||
|
||||
fg_pattern = grep_calloc(patterns, sizeof(*fg_pattern));
|
||||
r_pattern = grep_calloc(patterns, sizeof(*r_pattern));
|
||||
/*
|
||||
* XXX: fgrepcomp() and fastcomp() are workarounds for regexec() performance.
|
||||
* Optimizations should be done there.
|
||||
*/
|
||||
/* Check if cheating is allowed (always is for fgrep). */
|
||||
if (grepbehave == GREP_FIXED) {
|
||||
for (i = 0; i < patterns; ++i)
|
||||
fgrepcomp(&fg_pattern[i], pattern[i]);
|
||||
} else {
|
||||
for (i = 0; i < patterns; ++i) {
|
||||
if (fastcomp(&fg_pattern[i], pattern[i])) {
|
||||
/* Fall back to full regex library */
|
||||
c = regcomp(&r_pattern[i], pattern[i], cflags);
|
||||
if (c != 0) {
|
||||
regerror(c, &r_pattern[i], re_error,
|
||||
RE_ERROR_BUF);
|
||||
errx(2, "%s", re_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lbflag) {
|
||||
#ifdef _IOLBF
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
#else
|
||||
setlinebuf(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((aargc == 0 || aargc == 1) && !Hflag)
|
||||
hflag = true;
|
||||
|
||||
if (aargc == 0)
|
||||
exit(!procfile("-"));
|
||||
|
||||
if (dirbehave == DIR_RECURSE)
|
||||
c = grep_tree(aargv);
|
||||
else
|
||||
for (c = 0; aargc--; ++aargv) {
|
||||
if ((finclude || fexclude) && !file_matching(*aargv))
|
||||
continue;
|
||||
c+= procfile(*aargv);
|
||||
}
|
||||
|
||||
#ifndef WITHOUT_NLS
|
||||
catclose(catalog);
|
||||
#endif
|
||||
|
||||
/* Find out the correct return value according to the
|
||||
results and the command line option. */
|
||||
exit(c ? (notfound ? (qflag ? 0 : 2) : 0) : (notfound ? 2 : 1));
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
/* $NetBSD: grep.h,v 1.10 2018/08/12 09:03:21 christos Exp $ */
|
||||
/* $OpenBSD: grep.h,v 1.15 2010/04/05 03:03:55 tedu Exp $ */
|
||||
/* $FreeBSD: head/usr.bin/grep/grep.h 211496 2010-08-19 09:28:59Z des $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (c) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef WITHOUT_BZ2
|
||||
#include <bzlib.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#ifndef WITHOUT_GZIP
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITHOUT_NLS
|
||||
#define getstr(n) errstr[n]
|
||||
#else
|
||||
#include <nl_types.h>
|
||||
|
||||
extern nl_catd catalog;
|
||||
#define getstr(n) catgets(catalog, 1, n, errstr[n])
|
||||
#endif
|
||||
|
||||
extern const char *errstr[];
|
||||
|
||||
#define VERSION "2.5.1-FreeBSD"
|
||||
|
||||
#define GREP_FIXED 0
|
||||
#define GREP_BASIC 1
|
||||
#define GREP_EXTENDED 2
|
||||
|
||||
#define BINFILE_BIN 0
|
||||
#define BINFILE_SKIP 1
|
||||
#define BINFILE_TEXT 2
|
||||
|
||||
#define FILE_STDIO 0
|
||||
#define FILE_GZIP 1
|
||||
#define FILE_BZIP 2
|
||||
|
||||
#define DIR_READ 0
|
||||
#define DIR_SKIP 1
|
||||
#define DIR_RECURSE 2
|
||||
|
||||
#define DEV_READ 0
|
||||
#define DEV_SKIP 1
|
||||
|
||||
#define LINK_READ 0
|
||||
#define LINK_EXPLICIT 1
|
||||
#define LINK_SKIP 2
|
||||
|
||||
#define EXCL_PAT 0
|
||||
#define INCL_PAT 1
|
||||
|
||||
#define MAX_LINE_MATCHES 32
|
||||
|
||||
struct file {
|
||||
int fd;
|
||||
bool binary;
|
||||
};
|
||||
|
||||
struct str {
|
||||
off_t off;
|
||||
size_t len;
|
||||
char *dat;
|
||||
char *file;
|
||||
int line_no;
|
||||
};
|
||||
|
||||
struct epat {
|
||||
char *pat;
|
||||
int mode;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
size_t len;
|
||||
unsigned char *pattern;
|
||||
int qsBc[UCHAR_MAX + 1];
|
||||
/* flags */
|
||||
bool bol;
|
||||
bool eol;
|
||||
bool reversed;
|
||||
bool word;
|
||||
} fastgrep_t;
|
||||
|
||||
/* Flags passed to regcomp() and regexec() */
|
||||
extern int cflags, eflags;
|
||||
|
||||
/* Command line flags */
|
||||
extern bool Eflag, Fflag, Gflag, Hflag, Lflag,
|
||||
bflag, cflag, hflag, iflag, lflag, mflag, nflag, oflag,
|
||||
qflag, sflag, vflag, wflag, xflag;
|
||||
extern bool dexclude, dinclude, fexclude, finclude, lbflag, nullflag, nulldataflag;
|
||||
extern unsigned char line_sep;
|
||||
extern unsigned long long Aflag, Bflag, mcount;
|
||||
extern char *label;
|
||||
extern const char *color;
|
||||
extern int binbehave, devbehave, dirbehave, filebehave, grepbehave, linkbehave;
|
||||
|
||||
extern bool notfound;
|
||||
extern int tail;
|
||||
extern unsigned int dpatterns, fpatterns, patterns;
|
||||
extern char **pattern;
|
||||
extern struct epat *dpattern, *fpattern;
|
||||
extern regex_t *er_pattern, *r_pattern;
|
||||
extern fastgrep_t *fg_pattern;
|
||||
|
||||
/* For regex errors */
|
||||
#define RE_ERROR_BUF 512
|
||||
extern char re_error[RE_ERROR_BUF + 1]; /* Seems big enough */
|
||||
|
||||
/* util.c */
|
||||
bool file_matching(const char *fname);
|
||||
int procfile(const char *fn);
|
||||
int grep_tree(char **argv);
|
||||
void *grep_malloc(size_t size);
|
||||
void *grep_calloc(size_t nmemb, size_t size);
|
||||
void *grep_realloc(void *ptr, size_t size);
|
||||
char *grep_strdup(const char *str);
|
||||
void printline(struct str *line, int sep, regmatch_t *matches, int m);
|
||||
|
||||
/* queue.c */
|
||||
void enqueue(struct str *x);
|
||||
void printqueue(void);
|
||||
void clearqueue(void);
|
||||
|
||||
/* file.c */
|
||||
void grep_close(struct file *f);
|
||||
struct file *grep_open(const char *path);
|
||||
char *grep_fgetln(struct file *f, size_t *len);
|
||||
|
||||
/* fastgrep.c */
|
||||
int fastcomp(fastgrep_t *, const char *);
|
||||
void fgrepcomp(fastgrep_t *, const char *);
|
||||
int grep_search(fastgrep_t *, const unsigned char *, size_t, regmatch_t *);
|
|
@ -1,116 +0,0 @@
|
|||
/* $NetBSD: queue.c,v 1.5 2011/08/31 16:24:57 plunky Exp $ */
|
||||
/* $FreeBSD: head/usr.bin/grep/queue.c 211496 2010-08-19 09:28:59Z des $ */
|
||||
/*-
|
||||
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* A really poor man's queue. It does only what it has to and gets out of
|
||||
* Dodge. It is used in place of <sys/queue.h> to get a better performance.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <bsd/sys/cdefs.h>
|
||||
__RCSID("$NetBSD: queue.c,v 1.5 2011/08/31 16:24:57 plunky Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "grep.h"
|
||||
|
||||
struct qentry {
|
||||
STAILQ_ENTRY(qentry) list;
|
||||
struct str data;
|
||||
};
|
||||
|
||||
static STAILQ_HEAD(, qentry) queue = STAILQ_HEAD_INITIALIZER(queue);
|
||||
static unsigned long long count;
|
||||
|
||||
static struct qentry *dequeue(void);
|
||||
|
||||
void
|
||||
enqueue(struct str *x)
|
||||
{
|
||||
struct qentry *item;
|
||||
|
||||
item = grep_malloc(sizeof(struct qentry));
|
||||
item->data.dat = grep_malloc(sizeof(char) * x->len);
|
||||
item->data.len = x->len;
|
||||
item->data.line_no = x->line_no;
|
||||
item->data.off = x->off;
|
||||
memcpy(item->data.dat, x->dat, x->len);
|
||||
item->data.file = x->file;
|
||||
|
||||
STAILQ_INSERT_TAIL(&queue, item, list);
|
||||
|
||||
if (++count > Bflag) {
|
||||
item = dequeue();
|
||||
free(item->data.dat);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static struct qentry *
|
||||
dequeue(void)
|
||||
{
|
||||
struct qentry *item;
|
||||
|
||||
item = STAILQ_FIRST(&queue);
|
||||
if (item == NULL)
|
||||
return (NULL);
|
||||
|
||||
STAILQ_REMOVE_HEAD(&queue, list);
|
||||
--count;
|
||||
return (item);
|
||||
}
|
||||
|
||||
void
|
||||
printqueue(void)
|
||||
{
|
||||
struct qentry *item;
|
||||
|
||||
while ((item = dequeue()) != NULL) {
|
||||
printline(&item->data, '-', NULL, 0);
|
||||
free(item->data.dat);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clearqueue(void)
|
||||
{
|
||||
struct qentry *item;
|
||||
|
||||
while ((item = dequeue()) != NULL) {
|
||||
free(item->data.dat);
|
||||
free(item);
|
||||
}
|
||||
}
|
|
@ -1,500 +0,0 @@
|
|||
/* $NetBSD: util.c,v 1.19 2018/02/05 22:14:26 mrg Exp $ */
|
||||
/* $FreeBSD: head/usr.bin/grep/util.c 211496 2010-08-19 09:28:59Z des $ */
|
||||
/* $OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
|
||||
* Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
#endif
|
||||
|
||||
#include <bsd/sys/cdefs.h>
|
||||
__RCSID("$NetBSD: util.c,v 1.19 2018/02/05 22:14:26 mrg Exp $");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <fts.h>
|
||||
#include <libgen.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "grep.h"
|
||||
|
||||
static bool first, first_global = true;
|
||||
static unsigned long long since_printed;
|
||||
|
||||
static int procline(struct str *l, int);
|
||||
|
||||
bool
|
||||
file_matching(const char *fname)
|
||||
{
|
||||
char *fname_base, *fname_copy;
|
||||
unsigned int i;
|
||||
bool ret;
|
||||
|
||||
ret = finclude ? false : true;
|
||||
fname_copy = grep_strdup(fname);
|
||||
fname_base = basename(fname_copy);
|
||||
|
||||
for (i = 0; i < fpatterns; ++i) {
|
||||
if (fnmatch(fpattern[i].pat, fname, 0) == 0 ||
|
||||
fnmatch(fpattern[i].pat, fname_base, 0) == 0) {
|
||||
if (fpattern[i].mode == EXCL_PAT) {
|
||||
free(fname_copy);
|
||||
return (false);
|
||||
} else
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
free(fname_copy);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
dir_matching(const char *dname)
|
||||
{
|
||||
unsigned int i;
|
||||
bool ret;
|
||||
|
||||
ret = dinclude ? false : true;
|
||||
|
||||
for (i = 0; i < dpatterns; ++i) {
|
||||
if (dname != NULL &&
|
||||
fnmatch(dname, dpattern[i].pat, 0) == 0) {
|
||||
if (dpattern[i].mode == EXCL_PAT)
|
||||
return (false);
|
||||
else
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Processes a directory when a recursive search is performed with
|
||||
* the -R option. Each appropriate file is passed to procfile().
|
||||
*/
|
||||
int
|
||||
grep_tree(char **argv)
|
||||
{
|
||||
FTS *fts;
|
||||
FTSENT *p;
|
||||
char *d, *dir = NULL;
|
||||
int c, fts_flags;
|
||||
bool ok;
|
||||
|
||||
c = fts_flags = 0;
|
||||
|
||||
switch(linkbehave) {
|
||||
case LINK_EXPLICIT:
|
||||
fts_flags = FTS_COMFOLLOW;
|
||||
break;
|
||||
case LINK_SKIP:
|
||||
fts_flags = FTS_PHYSICAL;
|
||||
break;
|
||||
default:
|
||||
fts_flags = FTS_LOGICAL;
|
||||
|
||||
}
|
||||
|
||||
fts_flags |= FTS_NOSTAT | FTS_NOCHDIR;
|
||||
|
||||
if (!(fts = fts_open(argv, fts_flags, NULL)))
|
||||
err(2, "fts_open");
|
||||
while ((p = fts_read(fts)) != NULL) {
|
||||
switch (p->fts_info) {
|
||||
case FTS_DNR:
|
||||
/* FALLTHROUGH */
|
||||
case FTS_ERR:
|
||||
errx(2, "%s: %s", p->fts_path, strerror(p->fts_errno));
|
||||
break;
|
||||
case FTS_D:
|
||||
/* FALLTHROUGH */
|
||||
case FTS_DP:
|
||||
break;
|
||||
case FTS_DC:
|
||||
/* Print a warning for recursive directory loop */
|
||||
warnx("warning: %s: recursive directory loop",
|
||||
p->fts_path);
|
||||
break;
|
||||
default:
|
||||
/* Check for file exclusion/inclusion */
|
||||
ok = true;
|
||||
if (dexclude || dinclude) {
|
||||
if ((d = strrchr(p->fts_path, '/')) != NULL) {
|
||||
dir = grep_malloc(sizeof(char) *
|
||||
(d - p->fts_path + 1));
|
||||
memcpy(dir, p->fts_path,
|
||||
d - p->fts_path);
|
||||
dir[d - p->fts_path] = '\0';
|
||||
}
|
||||
ok = dir_matching(dir);
|
||||
free(dir);
|
||||
dir = NULL;
|
||||
}
|
||||
if (fexclude || finclude)
|
||||
ok &= file_matching(p->fts_path);
|
||||
|
||||
if (ok)
|
||||
c += procfile(p->fts_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fts_close(fts);
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Opens a file and processes it. Each file is processed line-by-line
|
||||
* passing the lines to procline().
|
||||
*/
|
||||
int
|
||||
procfile(const char *fn)
|
||||
{
|
||||
struct file *f;
|
||||
struct stat sb;
|
||||
struct str ln;
|
||||
mode_t s;
|
||||
int c, t;
|
||||
|
||||
if (mflag && (mcount <= 0))
|
||||
return (0);
|
||||
|
||||
if (strcmp(fn, "-") == 0) {
|
||||
fn = label != NULL ? label : getstr(1);
|
||||
f = grep_open(NULL);
|
||||
} else {
|
||||
if (!stat(fn, &sb)) {
|
||||
/* Check if we need to process the file */
|
||||
s = sb.st_mode & S_IFMT;
|
||||
if (s == S_IFDIR && dirbehave == DIR_SKIP)
|
||||
return (0);
|
||||
if ((s == S_IFIFO || s == S_IFCHR || s == S_IFBLK
|
||||
|| s == S_IFSOCK) && devbehave == DEV_SKIP)
|
||||
return (0);
|
||||
}
|
||||
f = grep_open(fn);
|
||||
}
|
||||
if (f == NULL) {
|
||||
if (!sflag)
|
||||
warn("%s", fn);
|
||||
if (errno == ENOENT)
|
||||
notfound = true;
|
||||
return (0);
|
||||
}
|
||||
|
||||
ln.file = grep_malloc(strlen(fn) + 1);
|
||||
strcpy(ln.file, fn);
|
||||
ln.line_no = 0;
|
||||
ln.len = 0;
|
||||
tail = 0;
|
||||
ln.off = -1;
|
||||
|
||||
for (first = true, c = 0; c == 0 || !(lflag || qflag); ) {
|
||||
ln.off += ln.len + 1;
|
||||
if ((ln.dat = grep_fgetln(f, &ln.len)) == NULL || ln.len == 0)
|
||||
break;
|
||||
if (ln.len > 0 && ln.dat[ln.len - 1] == line_sep)
|
||||
--ln.len;
|
||||
ln.line_no++;
|
||||
|
||||
/* Return if we need to skip a binary file */
|
||||
if (f->binary && binbehave == BINFILE_SKIP) {
|
||||
grep_close(f);
|
||||
free(ln.file);
|
||||
free(f);
|
||||
return (0);
|
||||
}
|
||||
/* Process the file line-by-line */
|
||||
t = procline(&ln, f->binary);
|
||||
c += t;
|
||||
|
||||
/* Count the matches if we have a match limit */
|
||||
if (mflag) {
|
||||
mcount -= t;
|
||||
if (mcount <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Bflag > 0)
|
||||
clearqueue();
|
||||
grep_close(f);
|
||||
|
||||
if (cflag) {
|
||||
if (!hflag)
|
||||
printf("%s:", ln.file);
|
||||
printf("%u%c", c, line_sep);
|
||||
}
|
||||
if (lflag && !qflag && c != 0)
|
||||
printf("%s%c", fn, line_sep);
|
||||
if (Lflag && !qflag && c == 0)
|
||||
printf("%s%c", fn, line_sep);
|
||||
if (c && !cflag && !lflag && !Lflag &&
|
||||
binbehave == BINFILE_BIN && f->binary && !qflag)
|
||||
printf(getstr(8), fn);
|
||||
|
||||
free(ln.file);
|
||||
free(f);
|
||||
return (c);
|
||||
}
|
||||
|
||||
#define iswword(x) (iswalnum((x)) || (x) == L'_')
|
||||
|
||||
/*
|
||||
* Processes a line comparing it with the specified patterns. Each pattern
|
||||
* is looped to be compared along with the full string, saving each and every
|
||||
* match, which is necessary to colorize the output and to count the
|
||||
* matches. The matching lines are passed to printline() to display the
|
||||
* appropriate output.
|
||||
*/
|
||||
static int
|
||||
procline(struct str *l, int nottext)
|
||||
{
|
||||
regmatch_t matches[MAX_LINE_MATCHES];
|
||||
regmatch_t pmatch;
|
||||
size_t st = 0;
|
||||
unsigned int i;
|
||||
int c = 0, m = 0, r = 0;
|
||||
|
||||
/* Loop to process the whole line */
|
||||
while (st <= l->len) {
|
||||
pmatch.rm_so = st;
|
||||
pmatch.rm_eo = l->len;
|
||||
|
||||
/* Loop to compare with all the patterns */
|
||||
for (i = 0; i < patterns; i++) {
|
||||
/*
|
||||
* XXX: grep_search() is a workaround for speed up and should be
|
||||
* removed in the future. See fastgrep.c.
|
||||
*/
|
||||
if (fg_pattern[i].pattern) {
|
||||
r = grep_search(&fg_pattern[i],
|
||||
(unsigned char *)l->dat,
|
||||
l->len, &pmatch);
|
||||
r = (r == 0) ? 0 : REG_NOMATCH;
|
||||
st = pmatch.rm_eo;
|
||||
} else {
|
||||
r = regexec(&r_pattern[i], l->dat, 1,
|
||||
&pmatch, eflags);
|
||||
r = (r == 0) ? 0 : REG_NOMATCH;
|
||||
st = pmatch.rm_eo;
|
||||
}
|
||||
if (r == REG_NOMATCH)
|
||||
continue;
|
||||
/* Check for full match */
|
||||
if (xflag &&
|
||||
(pmatch.rm_so != 0 ||
|
||||
(size_t)pmatch.rm_eo != l->len))
|
||||
continue;
|
||||
/* Check for whole word match */
|
||||
if (fg_pattern[i].word && pmatch.rm_so != 0) {
|
||||
wchar_t wbegin, wend;
|
||||
|
||||
wbegin = wend = L' ';
|
||||
if (pmatch.rm_so != 0 &&
|
||||
sscanf(&l->dat[pmatch.rm_so - 1],
|
||||
"%lc", &wbegin) != 1)
|
||||
continue;
|
||||
if ((size_t)pmatch.rm_eo != l->len &&
|
||||
sscanf(&l->dat[pmatch.rm_eo],
|
||||
"%lc", &wend) != 1)
|
||||
continue;
|
||||
if (iswword(wbegin) || iswword(wend))
|
||||
continue;
|
||||
}
|
||||
c = 1;
|
||||
if (m < MAX_LINE_MATCHES)
|
||||
matches[m++] = pmatch;
|
||||
/* matches - skip further patterns */
|
||||
if ((color != NULL && !oflag) || qflag || lflag)
|
||||
break;
|
||||
}
|
||||
|
||||
if (vflag) {
|
||||
c = !c;
|
||||
break;
|
||||
}
|
||||
/* One pass if we are not recording matches */
|
||||
if ((color != NULL && !oflag) || qflag || lflag)
|
||||
break;
|
||||
|
||||
if (st == (size_t)pmatch.rm_so)
|
||||
break; /* No matches */
|
||||
}
|
||||
|
||||
if (c && binbehave == BINFILE_BIN && nottext)
|
||||
return (c); /* Binary file */
|
||||
|
||||
/* Dealing with the context */
|
||||
if ((tail || c) && !cflag && !qflag && !lflag && !Lflag) {
|
||||
if (c) {
|
||||
if ((Aflag || Bflag) && !first_global &&
|
||||
(first || since_printed > Bflag))
|
||||
printf("--\n");
|
||||
tail = Aflag;
|
||||
if (Bflag > 0)
|
||||
printqueue();
|
||||
printline(l, ':', matches, m);
|
||||
} else {
|
||||
printline(l, '-', matches, m);
|
||||
tail--;
|
||||
}
|
||||
first = false;
|
||||
first_global = false;
|
||||
since_printed = 0;
|
||||
} else {
|
||||
if (Bflag)
|
||||
enqueue(l);
|
||||
since_printed++;
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe malloc() for internal use.
|
||||
*/
|
||||
void *
|
||||
grep_malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = malloc(size)) == NULL)
|
||||
err(2, "malloc");
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe calloc() for internal use.
|
||||
*/
|
||||
void *
|
||||
grep_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = calloc(nmemb, size)) == NULL)
|
||||
err(2, "calloc");
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe realloc() for internal use.
|
||||
*/
|
||||
void *
|
||||
grep_realloc(void *ptr, size_t size)
|
||||
{
|
||||
|
||||
if ((ptr = realloc(ptr, size)) == NULL)
|
||||
err(2, "realloc");
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe strdup() for internal use.
|
||||
*/
|
||||
char *
|
||||
grep_strdup(const char *str)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
if ((ret = strdup(str)) == NULL)
|
||||
err(2, "strdup");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints a matching line according to the command line options.
|
||||
*/
|
||||
void
|
||||
printline(struct str *line, int sep, regmatch_t *matches, int m)
|
||||
{
|
||||
size_t a = 0;
|
||||
int i, n = 0;
|
||||
|
||||
if (!hflag) {
|
||||
if (nullflag == 0)
|
||||
fputs(line->file, stdout);
|
||||
else {
|
||||
printf("%s", line->file);
|
||||
putchar(0);
|
||||
}
|
||||
++n;
|
||||
}
|
||||
if (nflag) {
|
||||
if (n > 0)
|
||||
putchar(sep);
|
||||
printf("%d", line->line_no);
|
||||
++n;
|
||||
}
|
||||
if (bflag) {
|
||||
if (n > 0)
|
||||
putchar(sep);
|
||||
printf("%lld", (long long)line->off);
|
||||
++n;
|
||||
}
|
||||
if (n)
|
||||
putchar(sep);
|
||||
/* --color and -o */
|
||||
if ((oflag || color) && m > 0) {
|
||||
for (i = 0; i < m; i++) {
|
||||
if (!oflag)
|
||||
fwrite(line->dat + a, matches[i].rm_so - a, 1,
|
||||
stdout);
|
||||
if (color)
|
||||
fprintf(stdout, "\33[%sm\33[K", color);
|
||||
|
||||
fwrite(line->dat + matches[i].rm_so,
|
||||
matches[i].rm_eo - matches[i].rm_so, 1,
|
||||
stdout);
|
||||
|
||||
if (color)
|
||||
fprintf(stdout, "\33[m\33[K");
|
||||
a = matches[i].rm_eo;
|
||||
if (oflag)
|
||||
putchar('\n');
|
||||
}
|
||||
if (!oflag) {
|
||||
if (line->len - a > 0)
|
||||
fwrite(line->dat + a, line->len - a, 1, stdout);
|
||||
putchar(line_sep);
|
||||
}
|
||||
} else {
|
||||
fwrite(line->dat, line->len, 1, stdout);
|
||||
putchar(line_sep);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
# Makefile - hhl - /usr/src/world/mksh
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
#
|
||||
include ../../../config.mk
|
||||
progname = mksh
|
||||
skeldir = ${confdir}/skel
|
||||
|
@ -17,6 +17,6 @@ ifeq (${arch},x86_64)
|
|||
cflags += -malign-data=abi
|
||||
endif
|
||||
|
||||
post_build = install -Dm644 dot.mkshrc ${DESTDIR}/etc/skel
|
||||
post_build = install -Dm644 dot.mkshrc ${DESTDIR}/etc/skel/.mkshrc
|
||||
|
||||
include hhl.cprog.mk
|
||||
|
|
|
@ -58,7 +58,7 @@ smores() (
|
|||
)
|
||||
|
||||
# customise your favourite editor here; the first one found is used
|
||||
for EDITOR in "${EDITOR:-}" jupp jstar mcedit ed vi; do
|
||||
for EDITOR in "${EDITOR:-}" xvi kilo nano vim neovim emacs; do
|
||||
EDITOR=$(\\builtin whence -p "$EDITOR") || EDITOR=
|
||||
[[ -n $EDITOR && -x $EDITOR ]] && break
|
||||
EDITOR=
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <termios.h>
|
||||
/* shudder… */
|
||||
#include <termio.h>
|
||||
#ifdef _ISC_UNIX
|
||||
/* XXX imake style */
|
||||
#include <sys/sioctl.h>
|
||||
|
|
|
@ -7,6 +7,7 @@ binlinks = $(bindir)/paxtar $(bindir)/paxcpio $(bindir)/tar
|
|||
manlinks += paxtar.1@$(man1dir)/tar.1
|
||||
manlinks += paxcpio.1@$(man1dir)/cpio.1
|
||||
|
||||
libs += -lfts
|
||||
cflags += -fno-asynchronous-unwind-tables
|
||||
cflags += -fno-strict-aliasing
|
||||
cflags += -fstack-protector-strong
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
/*
|
||||
* External references from each source file
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef EXTERN
|
||||
__IDSTRING(rcsid_extern_h, "$MirOS: src/bin/pax/extern.h,v 1.39 2019/02/24 01:49:17 tg Exp $");
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# Makefile - hhl - /usr/src/world/usr.bin/sed
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
progname = sed
|
||||
cppflags += -DHAVE_CONFIG_H
|
||||
cppflags += -DLOCALEDIR=\"/usr/share/locale\"
|
||||
ldflags += -I.
|
||||
ldflags += -I./src
|
||||
ldflags += -I./lib/src
|
||||
libs += ./lib/libsed.a
|
||||
libs += -lacl
|
||||
|
||||
include hhl.cprog.mk
|
||||
|
||||
${binprog}: lib/libsed.a
|
||||
|
||||
lib/libsed.a:
|
||||
$(MAKE) -C lib
|
||||
|
||||
clean: clean-lib
|
||||
|
||||
clean-lib:
|
||||
$(MAKE) -C lib clean
|
||||
|
||||
.PHONY: clean-lib
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +0,0 @@
|
|||
# Makefile - hhl - /usr/src/world/usr.bin/sed/lib
|
||||
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
|
||||
#
|
||||
libname = sed
|
||||
doinstall = false
|
||||
cppflags += -DHAVE_CONFIG_H
|
||||
cflags += -O2
|
||||
ldflags += -I../
|
||||
ldflags += -I../src
|
||||
include hhl.staticlib.mk
|
|
@ -1,40 +0,0 @@
|
|||
/* A C macro for declaring that a function does not return.
|
||||
Copyright (C) 2011-2020 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/>. */
|
||||
|
||||
#ifndef _Noreturn
|
||||
# if (defined __cplusplus \
|
||||
&& ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
|
||||
|| (defined _MSC_VER && 1900 <= _MSC_VER)) \
|
||||
&& 0)
|
||||
/* [[noreturn]] is not practically usable, because with it the syntax
|
||||
extern _Noreturn void func (...);
|
||||
would not be valid; such a declaration would only be valid with 'extern'
|
||||
and '_Noreturn' swapped, or without the 'extern' keyword. However, some
|
||||
AIX system header files and several gnulib header files use precisely
|
||||
this syntax with 'extern'. */
|
||||
# define _Noreturn [[noreturn]]
|
||||
# elif ((!defined __cplusplus || defined __clang__) \
|
||||
&& (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
|
||||
|| 4 < __GNUC__ + (7 <= __GNUC_MINOR__)))
|
||||
/* _Noreturn works as-is. */
|
||||
# elif 2 < __GNUC__ + (8 <= __GNUC_MINOR__) || 0x5110 <= __SUNPRO_C
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
|
||||
# define _Noreturn __declspec (noreturn)
|
||||
# else
|
||||
# define _Noreturn
|
||||
# endif
|
||||
#endif
|
|
@ -1,52 +0,0 @@
|
|||
/* Test whether ACLs are well supported on this system.
|
||||
|
||||
Copyright 2013-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <acl.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* Return true if errno value ERRNUM indicates that ACLs are well
|
||||
supported on this system. ERRNUM should be an errno value obtained
|
||||
after an ACL-related system call fails. */
|
||||
bool
|
||||
acl_errno_valid (int errnum)
|
||||
{
|
||||
/* Recognize some common errors such as from an NFS mount that does
|
||||
not support ACLs, even when local drives do. */
|
||||
switch (errnum)
|
||||
{
|
||||
case EBUSY: return false;
|
||||
case EINVAL: return false;
|
||||
#if defined __APPLE__ && defined __MACH__
|
||||
case ENOENT: return false;
|
||||
#endif
|
||||
case ENOSYS: return false;
|
||||
|
||||
#if defined ENOTSUP && ENOTSUP != EOPNOTSUPP
|
||||
# if ENOTSUP != ENOSYS /* Needed for the MS-Windows port of GNU Emacs. */
|
||||
case ENOTSUP: return false;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
case EOPNOTSUPP: return false;
|
||||
default: return true;
|
||||
}
|
||||
}
|
|
@ -1,507 +0,0 @@
|
|||
/* Test whether a file has a nontrivial ACL. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include "acl-internal.h"
|
||||
|
||||
#if USE_ACL && HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
||||
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial. */
|
||||
int
|
||||
acl_extended_nontrivial (acl_t acl)
|
||||
{
|
||||
/* acl is non-trivial if it is non-empty. */
|
||||
return (acl_entries (acl) > 0);
|
||||
}
|
||||
|
||||
# else /* Linux, FreeBSD, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
int
|
||||
acl_access_nontrivial (acl_t acl)
|
||||
{
|
||||
/* acl is non-trivial if it has some entries other than for "user::",
|
||||
"group::", and "other::". Normally these three should be present
|
||||
at least, allowing us to write
|
||||
return (3 < acl_entries (acl));
|
||||
but the following code is more robust. */
|
||||
# if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Cygwin >= 2.5 */
|
||||
|
||||
acl_entry_t ace;
|
||||
int got_one;
|
||||
|
||||
for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
|
||||
got_one > 0;
|
||||
got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
|
||||
{
|
||||
acl_tag_t tag;
|
||||
if (acl_get_tag_type (ace, &tag) < 0)
|
||||
return -1;
|
||||
if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
|
||||
return 1;
|
||||
}
|
||||
return got_one;
|
||||
|
||||
# elif HAVE_ACL_TO_SHORT_TEXT /* IRIX */
|
||||
/* Don't use acl_get_entry: it is undocumented. */
|
||||
|
||||
int count = acl->acl_cnt;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
acl_entry_t ace = &acl->acl_entry[i];
|
||||
acl_tag_t tag = ace->ae_tag;
|
||||
|
||||
if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ
|
||||
|| tag == ACL_OTHER_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
# elif HAVE_ACL_FREE_TEXT /* Tru64 */
|
||||
/* Don't use acl_get_entry: it takes only one argument and does not work. */
|
||||
|
||||
int count = acl->acl_num;
|
||||
acl_entry_t ace;
|
||||
|
||||
for (ace = acl->acl_first; count > 0; ace = ace->next, count--)
|
||||
{
|
||||
acl_tag_t tag;
|
||||
acl_perm_t perm;
|
||||
|
||||
tag = ace->entry->acl_type;
|
||||
if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
|
||||
return 1;
|
||||
|
||||
perm = ace->entry->acl_perm;
|
||||
/* On Tru64, perm can also contain non-standard bits such as
|
||||
PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */
|
||||
if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
# else
|
||||
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
|
||||
int
|
||||
acl_default_nontrivial (acl_t acl)
|
||||
{
|
||||
/* acl is non-trivial if it is non-empty. */
|
||||
return (acl_entries (acl) > 0);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
|
||||
|
||||
/* Test an ACL retrieved with GETACL.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (int count, aclent_t *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
aclent_t *ace = &entries[i];
|
||||
|
||||
/* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
|
||||
If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
|
||||
We don't need to check ace->a_id in these cases. */
|
||||
if (!(ace->a_type == USER_OBJ
|
||||
|| ace->a_type == GROUP_OBJ
|
||||
|| ace->a_type == OTHER_OBJ
|
||||
/* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry
|
||||
sometimes. */
|
||||
|| ace->a_type == CLASS_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# ifdef ACE_GETACL
|
||||
|
||||
/* A shortcut for a bitmask. */
|
||||
# define NEW_ACE_WRITEA_DATA (NEW_ACE_WRITE_DATA | NEW_ACE_APPEND_DATA)
|
||||
|
||||
/* Test an ACL retrieved with ACE_GETACL.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_ace_nontrivial (int count, ace_t *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The flags in the ace_t structure changed in a binary incompatible way
|
||||
when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15.
|
||||
How to distinguish the two conventions at runtime?
|
||||
In the old convention, usually three ACEs have a_flags = ACE_OWNER /
|
||||
ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400. In the new
|
||||
convention, these values are not used. */
|
||||
int old_convention = 0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER))
|
||||
{
|
||||
old_convention = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (old_convention)
|
||||
/* Running on Solaris 10. */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ace_t *ace = &entries[i];
|
||||
|
||||
/* Note:
|
||||
If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat().
|
||||
If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat().
|
||||
We don't need to check ace->a_who in these cases. */
|
||||
if (!(ace->a_type == OLD_ALLOW
|
||||
&& (ace->a_flags == OLD_ACE_OWNER
|
||||
|| ace->a_flags == OLD_ACE_GROUP
|
||||
|| ace->a_flags == OLD_ACE_OTHER)))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Running on Solaris 10 (newer version) or Solaris 11. */
|
||||
unsigned int access_masks[6] =
|
||||
{
|
||||
0, /* owner@ deny */
|
||||
0, /* owner@ allow */
|
||||
0, /* group@ deny */
|
||||
0, /* group@ allow */
|
||||
0, /* everyone@ deny */
|
||||
0 /* everyone@ allow */
|
||||
};
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
ace_t *ace = &entries[i];
|
||||
unsigned int index1;
|
||||
unsigned int index2;
|
||||
|
||||
if (ace->a_type == NEW_ACE_ACCESS_ALLOWED_ACE_TYPE)
|
||||
index1 = 1;
|
||||
else if (ace->a_type == NEW_ACE_ACCESS_DENIED_ACE_TYPE)
|
||||
index1 = 0;
|
||||
else
|
||||
return 1;
|
||||
|
||||
if (ace->a_flags == NEW_ACE_OWNER)
|
||||
index2 = 0;
|
||||
else if (ace->a_flags == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP))
|
||||
index2 = 2;
|
||||
else if (ace->a_flags == NEW_ACE_EVERYONE)
|
||||
index2 = 4;
|
||||
else
|
||||
return 1;
|
||||
|
||||
access_masks[index1 + index2] |= ace->a_access_mask;
|
||||
}
|
||||
|
||||
/* The same bit shouldn't be both allowed and denied. */
|
||||
if (access_masks[0] & access_masks[1])
|
||||
return 1;
|
||||
if (access_masks[2] & access_masks[3])
|
||||
return 1;
|
||||
if (access_masks[4] & access_masks[5])
|
||||
return 1;
|
||||
|
||||
/* Check minimum masks. */
|
||||
if ((NEW_ACE_WRITE_NAMED_ATTRS
|
||||
| NEW_ACE_WRITE_ATTRIBUTES
|
||||
| NEW_ACE_WRITE_ACL
|
||||
| NEW_ACE_WRITE_OWNER)
|
||||
& ~ access_masks[1])
|
||||
return 1;
|
||||
access_masks[1] &= ~(NEW_ACE_WRITE_NAMED_ATTRS
|
||||
| NEW_ACE_WRITE_ATTRIBUTES
|
||||
| NEW_ACE_WRITE_ACL
|
||||
| NEW_ACE_WRITE_OWNER);
|
||||
if ((NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE)
|
||||
& ~ access_masks[5])
|
||||
return 1;
|
||||
access_masks[5] &= ~(NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE);
|
||||
|
||||
/* Check the allowed or denied bits. */
|
||||
switch ((access_masks[0] | access_masks[1])
|
||||
& ~(NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE))
|
||||
{
|
||||
case 0:
|
||||
case NEW_ACE_READ_DATA:
|
||||
case NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
switch ((access_masks[2] | access_masks[3])
|
||||
& ~(NEW_ACE_READ_NAMED_ATTRS
|
||||
| NEW_ACE_READ_ATTRIBUTES
|
||||
| NEW_ACE_READ_ACL
|
||||
| NEW_ACE_SYNCHRONIZE))
|
||||
{
|
||||
case 0:
|
||||
case NEW_ACE_READ_DATA:
|
||||
case NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
switch ((access_masks[4] | access_masks[5])
|
||||
& ~(NEW_ACE_WRITE_NAMED_ATTRS
|
||||
| NEW_ACE_WRITE_ATTRIBUTES
|
||||
| NEW_ACE_WRITE_ACL
|
||||
| NEW_ACE_WRITE_OWNER))
|
||||
{
|
||||
case 0:
|
||||
case NEW_ACE_READ_DATA:
|
||||
case NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA:
|
||||
case NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
case NEW_ACE_READ_DATA | NEW_ACE_WRITEA_DATA | NEW_ACE_EXECUTE:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check that the NEW_ACE_WRITE_DATA and NEW_ACE_APPEND_DATA bits are
|
||||
either both allowed or both denied. */
|
||||
if (((access_masks[0] & NEW_ACE_WRITE_DATA) != 0)
|
||||
!= ((access_masks[0] & NEW_ACE_APPEND_DATA) != 0))
|
||||
return 1;
|
||||
if (((access_masks[2] & NEW_ACE_WRITE_DATA) != 0)
|
||||
!= ((access_masks[2] & NEW_ACE_APPEND_DATA) != 0))
|
||||
return 1;
|
||||
if (((access_masks[4] & NEW_ACE_WRITE_DATA) != 0)
|
||||
!= ((access_masks[4] & NEW_ACE_APPEND_DATA) != 0))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && HAVE_GETACL /* HP-UX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (int count, struct acl_entry *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (count > 3)
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct acl_entry *ace = &entries[i];
|
||||
|
||||
if (ace->uid != ACL_NSUSER && ace->gid != ACL_NSGROUP)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# if HAVE_ACLV_H /* HP-UX >= 11.11 */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
aclv_nontrivial (int count, struct acl *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct acl *ace = &entries[i];
|
||||
|
||||
/* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
|
||||
If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
|
||||
We don't need to check ace->a_id in these cases. */
|
||||
if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == CLASS_OBJ
|
||||
|| ace->a_type == OTHER_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && (HAVE_ACLX_GET || HAVE_STATACL) /* AIX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (struct acl *a)
|
||||
{
|
||||
/* The normal way to iterate through an ACL is like this:
|
||||
struct acl_entry *ace;
|
||||
for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
|
||||
{
|
||||
struct ace_id *aei;
|
||||
switch (ace->ace_type)
|
||||
{
|
||||
case ACC_PERMIT:
|
||||
case ACC_DENY:
|
||||
case ACC_SPECIFY:
|
||||
...;
|
||||
}
|
||||
for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
|
||||
...
|
||||
}
|
||||
*/
|
||||
return (acl_last (a) != a->acl_ext ? 1 : 0);
|
||||
}
|
||||
|
||||
# if HAVE_ACLX_GET && defined ACL_AIX_WIP /* newer AIX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nfs4_nontrivial (nfs4_acl_int_t *a)
|
||||
{
|
||||
# if 1 /* let's try this first */
|
||||
return (a->aclEntryN > 0 ? 1 : 0);
|
||||
# else
|
||||
int count = a->aclEntryN;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
nfs4_ace_int_t *ace = &a->aclEntry[i];
|
||||
|
||||
if (!((ace->flags & ACE4_ID_SPECIAL) != 0
|
||||
&& (ace->aceWho.special_whoid == ACE4_WHO_OWNER
|
||||
|| ace->aceWho.special_whoid == ACE4_WHO_GROUP
|
||||
|| ace->aceWho.special_whoid == ACE4_WHO_EVERYONE)
|
||||
&& ace->aceType == ACE4_ACCESS_ALLOWED_ACE_TYPE
|
||||
&& ace->aceFlags == 0
|
||||
&& (ace->aceMask & ~(ACE4_READ_DATA | ACE4_LIST_DIRECTORY
|
||||
| ACE4_WRITE_DATA | ACE4_ADD_FILE
|
||||
| ACE4_EXECUTE)) == 0))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif USE_ACL && HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
/* Test an ACL retrieved with ACL_GET.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
int
|
||||
acl_nontrivial (int count, struct acl *entries)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
struct acl *ace = &entries[i];
|
||||
|
||||
/* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
|
||||
If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
|
||||
We don't need to check ace->a_id in these cases. */
|
||||
if (!(ace->a_type == USER_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == GROUP_OBJ /* no need to check ace->a_id here */
|
||||
|| ace->a_type == CLASS_OBJ
|
||||
|| ace->a_type == OTHER_OBJ))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
free_permission_context (struct permission_context *ctx)
|
||||
{
|
||||
#if USE_ACL
|
||||
# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
if (ctx->acl)
|
||||
acl_free (ctx->acl);
|
||||
# if !HAVE_ACL_TYPE_EXTENDED
|
||||
if (ctx->default_acl)
|
||||
acl_free (ctx->default_acl);
|
||||
# endif
|
||||
|
||||
# elif defined GETACL /* Solaris, Cygwin < 2.5 */
|
||||
free (ctx->entries);
|
||||
# ifdef ACE_GETACL
|
||||
free (ctx->ace_entries);
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
|
||||
# if HAVE_ACLV_H
|
||||
# endif
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
# endif
|
||||
#endif
|
||||
}
|
|
@ -1,302 +0,0 @@
|
|||
/* Internal implementation of access control lists. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* All systems define the ACL related API in <sys/acl.h>. */
|
||||
#if HAVE_SYS_ACL_H
|
||||
# include <sys/acl.h>
|
||||
#endif
|
||||
#if defined HAVE_FACL && ! defined GETACLCNT && defined ACL_CNT
|
||||
# define GETACLCNT ACL_CNT
|
||||
#endif
|
||||
|
||||
/* On Linux and Cygwin >= 2.5, additional ACL related API is available in
|
||||
<acl/libacl.h>. */
|
||||
#ifdef HAVE_ACL_LIBACL_H
|
||||
# include <acl/libacl.h>
|
||||
#endif
|
||||
|
||||
/* On HP-UX >= 11.11, additional ACL API is available in <aclv.h>. */
|
||||
#if HAVE_ACLV_H
|
||||
# include <sys/types.h>
|
||||
# include <aclv.h>
|
||||
/* HP-UX 11.11 lacks these declarations. */
|
||||
extern int acl (char *, int, int, struct acl *);
|
||||
extern int aclsort (int, int, struct acl *);
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <limits.h>
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
# define SIZE_MAX ((size_t) -1)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FCHMOD
|
||||
# define HAVE_FCHMOD false
|
||||
# define fchmod(fd, mode) (-1)
|
||||
#endif
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef ACL_INTERNAL_INLINE
|
||||
# define ACL_INTERNAL_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#if USE_ACL
|
||||
|
||||
# if HAVE_ACL_GET_FILE
|
||||
/* POSIX 1003.1e (draft 17 -- abandoned) specific version. */
|
||||
/* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
|
||||
# ifndef MIN_ACL_ENTRIES
|
||||
# define MIN_ACL_ENTRIES 4
|
||||
# endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
# ifdef HAVE_ACL_GET_FD
|
||||
/* Most platforms have a 1-argument acl_get_fd, only OSF/1 has a 2-argument
|
||||
macro(!). */
|
||||
# if HAVE_ACL_FREE_TEXT /* OSF/1 */
|
||||
ACL_INTERNAL_INLINE acl_t
|
||||
rpl_acl_get_fd (int fd)
|
||||
{
|
||||
return acl_get_fd (fd, ACL_TYPE_ACCESS);
|
||||
}
|
||||
# undef acl_get_fd
|
||||
# define acl_get_fd rpl_acl_get_fd
|
||||
# endif
|
||||
# else
|
||||
# define HAVE_ACL_GET_FD false
|
||||
# undef acl_get_fd
|
||||
# define acl_get_fd(fd) (NULL)
|
||||
# endif
|
||||
|
||||
/* POSIX 1003.1e (draft 17) */
|
||||
# ifdef HAVE_ACL_SET_FD
|
||||
/* Most platforms have a 2-argument acl_set_fd, only OSF/1 has a 3-argument
|
||||
macro(!). */
|
||||
# if HAVE_ACL_FREE_TEXT /* OSF/1 */
|
||||
ACL_INTERNAL_INLINE int
|
||||
rpl_acl_set_fd (int fd, acl_t acl)
|
||||
{
|
||||
return acl_set_fd (fd, ACL_TYPE_ACCESS, acl);
|
||||
}
|
||||
# undef acl_set_fd
|
||||
# define acl_set_fd rpl_acl_set_fd
|
||||
# endif
|
||||
# else
|
||||
# define HAVE_ACL_SET_FD false
|
||||
# undef acl_set_fd
|
||||
# define acl_set_fd(fd, acl) (-1)
|
||||
# endif
|
||||
|
||||
/* POSIX 1003.1e (draft 13) */
|
||||
# if ! HAVE_ACL_FREE_TEXT
|
||||
# define acl_free_text(buf) acl_free (buf)
|
||||
# endif
|
||||
|
||||
/* Linux-specific */
|
||||
/* Cygwin >= 2.5 implements this function, but it returns 1 for all
|
||||
directories, thus is unusable. */
|
||||
# if !defined HAVE_ACL_EXTENDED_FILE || defined __CYGWIN__
|
||||
# undef HAVE_ACL_EXTENDED_FILE
|
||||
# define HAVE_ACL_EXTENDED_FILE false
|
||||
# define acl_extended_file(name) (-1)
|
||||
# endif
|
||||
|
||||
# if ! defined HAVE_ACL_FROM_MODE && ! defined HAVE_ACL_FROM_TEXT
|
||||
# define acl_from_mode (NULL)
|
||||
# endif
|
||||
|
||||
/* Set to 0 if a file's mode is stored independently from the ACL. */
|
||||
# if (HAVE_ACL_COPY_EXT_NATIVE && HAVE_ACL_CREATE_ENTRY_NP) || defined __sgi /* Mac OS X, IRIX */
|
||||
# define MODE_INSIDE_ACL 0
|
||||
# endif
|
||||
|
||||
/* Return the number of entries in ACL.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
/* Define a replacement for acl_entries if needed. (Only Linux has it.) */
|
||||
# if !HAVE_ACL_ENTRIES
|
||||
# define acl_entries rpl_acl_entries
|
||||
extern int acl_entries (acl_t);
|
||||
# endif
|
||||
|
||||
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial. */
|
||||
extern int acl_extended_nontrivial (acl_t);
|
||||
# else
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
extern int acl_access_nontrivial (acl_t);
|
||||
|
||||
/* ACL is an ACL, from a file, stored as type ACL_TYPE_DEFAULT.
|
||||
Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
|
||||
Return -1 and set errno upon failure to determine it. */
|
||||
extern int acl_default_nontrivial (acl_t);
|
||||
# endif
|
||||
|
||||
# elif HAVE_FACL && defined GETACL /* Solaris, Cygwin < 2.5, not HP-UX */
|
||||
|
||||
/* Set to 0 if a file's mode is stored independently from the ACL. */
|
||||
# if defined __CYGWIN__ /* Cygwin */
|
||||
# define MODE_INSIDE_ACL 0
|
||||
# endif
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (int count, aclent_t *entries) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
# ifdef ACE_GETACL /* Solaris 10 */
|
||||
|
||||
/* Test an ACL retrieved with ACE_GETACL.
|
||||
Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_ace_nontrivial (int count, ace_t *entries) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Definitions for when the built executable is executed on Solaris 10
|
||||
(newer version) or Solaris 11. */
|
||||
/* For a_type. */
|
||||
# define OLD_ALLOW 0
|
||||
# define OLD_DENY 1
|
||||
# define NEW_ACE_ACCESS_ALLOWED_ACE_TYPE 0 /* replaces ALLOW */
|
||||
# define NEW_ACE_ACCESS_DENIED_ACE_TYPE 1 /* replaces DENY */
|
||||
/* For a_flags. */
|
||||
# define OLD_ACE_OWNER 0x0100
|
||||
# define OLD_ACE_GROUP 0x0200
|
||||
# define OLD_ACE_OTHER 0x0400
|
||||
# define NEW_ACE_OWNER 0x1000
|
||||
# define NEW_ACE_GROUP 0x2000
|
||||
# define NEW_ACE_IDENTIFIER_GROUP 0x0040
|
||||
# define NEW_ACE_EVERYONE 0x4000
|
||||
/* For a_access_mask. */
|
||||
# define NEW_ACE_READ_DATA 0x001 /* corresponds to 'r' */
|
||||
# define NEW_ACE_WRITE_DATA 0x002 /* corresponds to 'w' */
|
||||
# define NEW_ACE_APPEND_DATA 0x004
|
||||
# define NEW_ACE_READ_NAMED_ATTRS 0x008
|
||||
# define NEW_ACE_WRITE_NAMED_ATTRS 0x010
|
||||
# define NEW_ACE_EXECUTE 0x020
|
||||
# define NEW_ACE_DELETE_CHILD 0x040
|
||||
# define NEW_ACE_READ_ATTRIBUTES 0x080
|
||||
# define NEW_ACE_WRITE_ATTRIBUTES 0x100
|
||||
# define NEW_ACE_DELETE 0x10000
|
||||
# define NEW_ACE_READ_ACL 0x20000
|
||||
# define NEW_ACE_WRITE_ACL 0x40000
|
||||
# define NEW_ACE_WRITE_OWNER 0x80000
|
||||
# define NEW_ACE_SYNCHRONIZE 0x100000
|
||||
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (int count, struct acl_entry *entries);
|
||||
|
||||
# if HAVE_ACLV_H /* HP-UX >= 11.11 */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int aclv_nontrivial (int count, struct acl *entries);
|
||||
|
||||
# endif
|
||||
|
||||
# elif HAVE_ACLX_GET && 0 /* AIX */
|
||||
|
||||
/* TODO */
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (struct acl *a);
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
|
||||
/* Return 1 if the given ACL is non-trivial.
|
||||
Return 0 if it is trivial, i.e. equivalent to a simple stat() mode. */
|
||||
extern int acl_nontrivial (int count, struct acl *entries);
|
||||
|
||||
# endif
|
||||
|
||||
/* Set to 1 if a file's mode is implicit by the ACL. */
|
||||
# ifndef MODE_INSIDE_ACL
|
||||
# define MODE_INSIDE_ACL 1
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
struct permission_context {
|
||||
mode_t mode;
|
||||
#if USE_ACL
|
||||
# if HAVE_ACL_GET_FILE /* Linux, FreeBSD, Mac OS X, IRIX, Tru64, Cygwin >= 2.5 */
|
||||
acl_t acl;
|
||||
# if !HAVE_ACL_TYPE_EXTENDED
|
||||
acl_t default_acl;
|
||||
# endif
|
||||
bool acls_not_supported;
|
||||
|
||||
# elif defined GETACL /* Solaris, Cygwin < 2.5 */
|
||||
int count;
|
||||
aclent_t *entries;
|
||||
# ifdef ACE_GETACL
|
||||
int ace_count;
|
||||
ace_t *ace_entries;
|
||||
# endif
|
||||
|
||||
# elif HAVE_GETACL /* HP-UX */
|
||||
struct acl_entry entries[NACLENTRIES];
|
||||
int count;
|
||||
# if HAVE_ACLV_H
|
||||
struct acl aclv_entries[NACLVENTRIES];
|
||||
int aclv_count;
|
||||
# endif
|
||||
|
||||
# elif HAVE_STATACL /* older AIX */
|
||||
union { struct acl a; char room[4096]; } u;
|
||||
bool have_u;
|
||||
|
||||
# elif HAVE_ACLSORT /* NonStop Kernel */
|
||||
struct acl entries[NACLENTRIES];
|
||||
int count;
|
||||
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
int get_permissions (const char *, int, mode_t, struct permission_context *);
|
||||
int set_permissions (struct permission_context *, const char *, int);
|
||||
void free_permission_context (struct permission_context *);
|
||||
|
||||
_GL_INLINE_HEADER_END
|
|
@ -1,35 +0,0 @@
|
|||
/* acl.c - access control lists
|
||||
|
||||
Copyright (C) 2002, 2008-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert. */
|
||||
|
||||
#ifndef _GL_ACL_H
|
||||
#define _GL_ACL_H 1
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
bool acl_errno_valid (int) _GL_ATTRIBUTE_CONST;
|
||||
int file_has_acl (char const *, struct stat const *);
|
||||
int qset_acl (char const *, int, mode_t);
|
||||
int set_acl (char const *, int, mode_t);
|
||||
int qcopy_acl (char const *, int, char const *, int, mode_t);
|
||||
int copy_acl (char const *, int, char const *, int, mode_t);
|
||||
int chmod_or_fchmod (char const *, int, mode_t);
|
||||
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
/* Determine alignment of types.
|
||||
Copyright (C) 2003-2004, 2006, 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _ALIGNOF_H
|
||||
#define _ALIGNOF_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* alignof_slot (TYPE)
|
||||
Determine the alignment of a structure slot (field) of a given type,
|
||||
at compile time. Note that the result depends on the ABI.
|
||||
This is the same as alignof (TYPE) and _Alignof (TYPE), defined in
|
||||
<stdalign.h> if __alignof_is_defined is 1.
|
||||
Note: The result cannot be used as a value for an 'enum' constant,
|
||||
due to bugs in HP-UX 10.20 cc and AIX 3.2.5 xlc. */
|
||||
#if defined __cplusplus
|
||||
template <class type> struct alignof_helper { char __slot1; type __slot2; };
|
||||
# define alignof_slot(type) offsetof (alignof_helper<type>, __slot2)
|
||||
#else
|
||||
# define alignof_slot(type) offsetof (struct { char __slot1; type __slot2; }, __slot2)
|
||||
#endif
|
||||
|
||||
/* alignof_type (TYPE)
|
||||
Determine the good alignment of an object of the given type at compile time.
|
||||
Note that this is not necessarily the same as alignof_slot(type).
|
||||
For example, with GNU C on x86 platforms: alignof_type(double) = 8, but
|
||||
- when -malign-double is not specified: alignof_slot(double) = 4,
|
||||
- when -malign-double is specified: alignof_slot(double) = 8.
|
||||
Note: The result cannot be used as a value for an 'enum' constant,
|
||||
due to bugs in HP-UX 10.20 cc and AIX 3.2.5 xlc. */
|
||||
#if defined __GNUC__ || defined __IBM__ALIGNOF__
|
||||
# define alignof_type __alignof__
|
||||
#else
|
||||
# define alignof_type alignof_slot
|
||||
#endif
|
||||
|
||||
#endif /* _ALIGNOF_H */
|
|
@ -1,72 +0,0 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
/* Memory allocation on the stack.
|
||||
|
||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2020 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
|
||||
means there is a real alloca function. */
|
||||
#ifndef _GL_ALLOCA_H
|
||||
#define _GL_ALLOCA_H
|
||||
|
||||
/* alloca (N) returns a pointer to N bytes of memory
|
||||
allocated on the stack, which will last until the function returns.
|
||||
Use of alloca should be avoided:
|
||||
- inside arguments of function calls - undefined behaviour,
|
||||
- in inline functions - the allocation may actually last until the
|
||||
calling function returns,
|
||||
- for huge N (say, N >= 65536) - you never know how large (or small)
|
||||
the stack is, and when the stack cannot fulfill the memory allocation
|
||||
request, the program just crashes.
|
||||
*/
|
||||
|
||||
#ifndef alloca
|
||||
# ifdef __GNUC__
|
||||
/* Some version of mingw have an <alloca.h> that causes trouble when
|
||||
included after 'alloca' gets defined as a macro. As a workaround, include
|
||||
this <alloca.h> first and define 'alloca' as a macro afterwards. */
|
||||
# if (defined _WIN32 && ! defined __CYGWIN__) && 1
|
||||
# include_next <alloca.h>
|
||||
# endif
|
||||
# define alloca __builtin_alloca
|
||||
# elif defined _AIX
|
||||
# define alloca __alloca
|
||||
# elif defined _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
# elif defined __DECC && defined __VMS
|
||||
# define alloca __ALLOCA
|
||||
# elif defined __TANDEM && defined _TNS_E_TARGET
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *_alloca (unsigned short);
|
||||
# pragma intrinsic (_alloca)
|
||||
# define alloca _alloca
|
||||
# elif defined __MVS__
|
||||
# include <stdlib.h>
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *alloca (size_t);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _GL_ALLOCA_H */
|
|
@ -1,71 +0,0 @@
|
|||
/* Memory allocation on the stack.
|
||||
|
||||
Copyright (C) 1995, 1999, 2001-2004, 2006-2020 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published
|
||||
by the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; if not, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
|
||||
means there is a real alloca function. */
|
||||
#ifndef _GL_ALLOCA_H
|
||||
#define _GL_ALLOCA_H
|
||||
|
||||
/* alloca (N) returns a pointer to N bytes of memory
|
||||
allocated on the stack, which will last until the function returns.
|
||||
Use of alloca should be avoided:
|
||||
- inside arguments of function calls - undefined behaviour,
|
||||
- in inline functions - the allocation may actually last until the
|
||||
calling function returns,
|
||||
- for huge N (say, N >= 65536) - you never know how large (or small)
|
||||
the stack is, and when the stack cannot fulfill the memory allocation
|
||||
request, the program just crashes.
|
||||
*/
|
||||
|
||||
#ifndef alloca
|
||||
# ifdef __GNUC__
|
||||
/* Some version of mingw have an <alloca.h> that causes trouble when
|
||||
included after 'alloca' gets defined as a macro. As a workaround, include
|
||||
this <alloca.h> first and define 'alloca' as a macro afterwards. */
|
||||
# if (defined _WIN32 && ! defined __CYGWIN__) && @HAVE_ALLOCA_H@
|
||||
# include_next <alloca.h>
|
||||
# endif
|
||||
# define alloca __builtin_alloca
|
||||
# elif defined _AIX
|
||||
# define alloca __alloca
|
||||
# elif defined _MSC_VER
|
||||
# include <malloc.h>
|
||||
# define alloca _alloca
|
||||
# elif defined __DECC && defined __VMS
|
||||
# define alloca __ALLOCA
|
||||
# elif defined __TANDEM && defined _TNS_E_TARGET
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *_alloca (unsigned short);
|
||||
# pragma intrinsic (_alloca)
|
||||
# define alloca _alloca
|
||||
# elif defined __MVS__
|
||||
# include <stdlib.h>
|
||||
# else
|
||||
# include <stddef.h>
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
void *alloca (size_t);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* _GL_ALLOCA_H */
|
|
@ -1,26 +0,0 @@
|
|||
/* A C macro for declaring that specific arguments must not be NULL.
|
||||
Copyright (C) 2009-2020 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/>. */
|
||||
|
||||
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
|
||||
that the values passed as arguments n, ..., m must be non-NULL pointers.
|
||||
n = 1 stands for the first argument, n = 2 for the second argument etc. */
|
||||
#ifndef _GL_ARG_NONNULL
|
||||
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
|
||||
# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define _GL_ARG_NONNULL(params)
|
||||
# endif
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
/* basename.c -- return the last element in a file name
|
||||
|
||||
Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2020 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/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Return the address of the last file name component of NAME. If
|
||||
NAME has no relative file name components because it is a file
|
||||
system root, return the empty string. */
|
||||
|
||||
char *
|
||||
last_component (char const *name)
|
||||
{
|
||||
char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
|
||||
char const *p;
|
||||
bool saw_slash = false;
|
||||
|
||||
while (ISSLASH (*base))
|
||||
base++;
|
||||
|
||||
for (p = base; *p; p++)
|
||||
{
|
||||
if (ISSLASH (*p))
|
||||
saw_slash = true;
|
||||
else if (saw_slash)
|
||||
{
|
||||
base = p;
|
||||
saw_slash = false;
|
||||
}
|
||||
}
|
||||
|
||||
return (char *) base;
|
||||
}
|
||||
|
||||
/* Return the length of the basename NAME. Typically NAME is the
|
||||
value returned by base_name or last_component. Act like strlen
|
||||
(NAME), except omit all trailing slashes. */
|
||||
|
||||
size_t
|
||||
base_len (char const *name)
|
||||
{
|
||||
size_t len;
|
||||
size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
|
||||
|
||||
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
||||
continue;
|
||||
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
|
||||
&& ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
|
||||
return 2;
|
||||
|
||||
if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
|
||||
&& len == prefix_len && ISSLASH (name[prefix_len]))
|
||||
return prefix_len + 1;
|
||||
|
||||
return len;
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
/* Binary mode I/O.
|
||||
Copyright 2017-2020 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/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define BINARY_IO_INLINE _GL_EXTERN_INLINE
|
||||
#include "binary-io.h"
|
||||
|
||||
#if defined __DJGPP__ || defined __EMX__
|
||||
# include <unistd.h>
|
||||
|
||||
int
|
||||
set_binary_mode (int fd, int mode)
|
||||
{
|
||||
if (isatty (fd))
|
||||
/* If FD refers to a console (not a pipe, not a regular file),
|
||||
O_TEXT is the only reasonable mode, both on input and on output.
|
||||
Silently ignore the request. If we were to return -1 here,
|
||||
all programs that use xset_binary_mode would fail when run
|
||||
with console input or console output. */
|
||||
return O_TEXT;
|
||||
else
|
||||
return __gl_setmode (fd, mode);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,77 +0,0 @@
|
|||
/* Binary mode I/O.
|
||||
Copyright (C) 2001, 2003, 2005, 2008-2020 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/>. */
|
||||
|
||||
#ifndef _BINARY_H
|
||||
#define _BINARY_H
|
||||
|
||||
/* For systems that distinguish between text and binary I/O.
|
||||
O_BINARY is guaranteed by the gnulib <fcntl.h>. */
|
||||
#include <fcntl.h>
|
||||
|
||||
/* The MSVC7 <stdio.h> doesn't like to be included after '#define fileno ...',
|
||||
so we include it here first. */
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef BINARY_IO_INLINE
|
||||
# define BINARY_IO_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#if O_BINARY
|
||||
# if defined __EMX__ || defined __DJGPP__ || defined __CYGWIN__
|
||||
# include <io.h> /* declares setmode() */
|
||||
# define __gl_setmode setmode
|
||||
# else
|
||||
# define __gl_setmode _setmode
|
||||
# undef fileno
|
||||
# define fileno _fileno
|
||||
# endif
|
||||
#else
|
||||
/* On reasonable systems, binary I/O is the only choice. */
|
||||
/* Use a function rather than a macro, to avoid gcc warnings
|
||||
"warning: statement with no effect". */
|
||||
BINARY_IO_INLINE int
|
||||
__gl_setmode (int fd _GL_UNUSED, int mode _GL_UNUSED)
|
||||
{
|
||||
return O_BINARY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set FD's mode to MODE, which should be either O_TEXT or O_BINARY.
|
||||
Return the old mode if successful, -1 (setting errno) on failure.
|
||||
Ordinarily this function would be called 'setmode', since that is
|
||||
its name on MS-Windows, but it is called 'set_binary_mode' here
|
||||
to avoid colliding with a BSD function of another name. */
|
||||
|
||||
#if defined __DJGPP__ || defined __EMX__
|
||||
extern int set_binary_mode (int fd, int mode);
|
||||
#else
|
||||
BINARY_IO_INLINE int
|
||||
set_binary_mode (int fd, int mode)
|
||||
{
|
||||
return __gl_setmode (fd, mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This macro is obsolescent. */
|
||||
#define SET_BINARY(fd) ((void) set_binary_mode (fd, O_BINARY))
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* _BINARY_H */
|
|
@ -1,316 +0,0 @@
|
|||
/* C++ compatible function declaration macros.
|
||||
Copyright (C) 2010-2020 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/>. */
|
||||
|
||||
#ifndef _GL_CXXDEFS_H
|
||||
#define _GL_CXXDEFS_H
|
||||
|
||||
/* Begin/end the GNULIB_NAMESPACE namespace. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
|
||||
# define _GL_END_NAMESPACE }
|
||||
#else
|
||||
# define _GL_BEGIN_NAMESPACE
|
||||
# define _GL_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
/* The three most frequent use cases of these macros are:
|
||||
|
||||
* For providing a substitute for a function that is missing on some
|
||||
platforms, but is declared and works fine on the platforms on which
|
||||
it exists:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if !@HAVE_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on all platforms,
|
||||
but is broken/insufficient and needs to be replaced on some platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on some platforms
|
||||
but is broken/insufficient and needs to be replaced on some of them and
|
||||
is additionally either missing or undeclared on some other platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* _GL_EXTERN_C declaration;
|
||||
performs the declaration with C linkage. */
|
||||
#if defined __cplusplus
|
||||
# define _GL_EXTERN_C extern "C"
|
||||
#else
|
||||
# define _GL_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
|
||||
declares a replacement function, named rpl_func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
|
||||
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
|
||||
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
|
||||
|
||||
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
|
||||
declares the system function, named func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype func parameters_and_attributes
|
||||
|
||||
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping rpl_func in an object with an inline conversion operator
|
||||
avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::rpl_func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
|
||||
except that the C function rpl_func may have a slightly different
|
||||
declaration. A cast is used to silence the "invalid conversion" error
|
||||
that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::rpl_func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to the system provided function func, if GNULIB_NAMESPACE
|
||||
is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping func in an object with an inline conversion operator
|
||||
avoids a reference to func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function func may have a slightly different declaration.
|
||||
A cast is used to silence the "invalid conversion" error that would
|
||||
otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function is picked among a set of overloaded functions,
|
||||
namely the one with rettype2 and parameters2. Two consecutive casts
|
||||
are used to silence the "cannot find a match" and "invalid conversion"
|
||||
errors that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* The outer cast must be a reinterpret_cast.
|
||||
The inner cast: When the function is defined as a set of overloaded
|
||||
functions, it works as a static_cast<>, choosing the designated variant.
|
||||
When the function is defined as a single variant, it works as a
|
||||
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN (func);
|
||||
causes a warning to be emitted when ::func is used but not when
|
||||
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
|
||||
variants. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN_1(func,namespace) \
|
||||
_GL_CXXALIASWARN_2 (func, namespace)
|
||||
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_WARN_ON_USE (func, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
|
||||
causes a warning to be emitted when the given overloaded variant of ::func
|
||||
is used but not when GNULIB_NAMESPACE::func is used. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
|
||||
GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
|
||||
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
#endif /* _GL_CXXDEFS_H */
|
|
@ -1,3 +0,0 @@
|
|||
#include <config.h>
|
||||
#define C_CTYPE_INLINE _GL_EXTERN_INLINE
|
||||
#include "c-ctype.h"
|
|
@ -1,366 +0,0 @@
|
|||
/* Character handling in C locale.
|
||||
|
||||
These functions work like the corresponding functions in <ctype.h>,
|
||||
except that they have the C (POSIX) locale hardwired, whereas the
|
||||
<ctype.h> functions' behaviour depends on the current locale set via
|
||||
setlocale.
|
||||
|
||||
Copyright (C) 2000-2003, 2006, 2008-2020 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/>. */
|
||||
|
||||
#ifndef C_CTYPE_H
|
||||
#define C_CTYPE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _GL_INLINE_HEADER_BEGIN
|
||||
#error "Please include config.h first."
|
||||
#endif
|
||||
_GL_INLINE_HEADER_BEGIN
|
||||
#ifndef C_CTYPE_INLINE
|
||||
# define C_CTYPE_INLINE _GL_INLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* The functions defined in this file assume the "C" locale and a character
|
||||
set without diacritics (ASCII-US or EBCDIC-US or something like that).
|
||||
Even if the "C" locale on a particular system is an extension of the ASCII
|
||||
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
|
||||
is ISO-8859-1), the functions in this file recognize only the ASCII
|
||||
characters. */
|
||||
|
||||
|
||||
#if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
|
||||
&& ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
|
||||
&& (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
|
||||
&& ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
|
||||
&& ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
|
||||
&& ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
|
||||
&& ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
|
||||
&& ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
|
||||
&& ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
|
||||
&& ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
|
||||
&& ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
|
||||
&& ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
|
||||
&& ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
|
||||
&& ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
|
||||
&& ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
|
||||
&& ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
|
||||
&& ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
|
||||
&& ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
|
||||
&& ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
|
||||
&& ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
|
||||
&& ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
|
||||
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
|
||||
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
|
||||
/* The character set is ASCII or one of its variants or extensions, not EBCDIC.
|
||||
Testing the value of '\n' and '\r' is not relevant. */
|
||||
# define C_CTYPE_ASCII 1
|
||||
#elif ! (' ' == '\x40' && '0' == '\xf0' \
|
||||
&& 'A' == '\xc1' && 'J' == '\xd1' && 'S' == '\xe2' \
|
||||
&& 'a' == '\x81' && 'j' == '\x91' && 's' == '\xa2')
|
||||
# error "Only ASCII and EBCDIC are supported"
|
||||
#endif
|
||||
|
||||
#if 'A' < 0
|
||||
# error "EBCDIC and char is signed -- not supported"
|
||||
#endif
|
||||
|
||||
/* Cases for control characters. */
|
||||
|
||||
#define _C_CTYPE_CNTRL \
|
||||
case '\a': case '\b': case '\f': case '\n': \
|
||||
case '\r': case '\t': case '\v': \
|
||||
_C_CTYPE_OTHER_CNTRL
|
||||
|
||||
/* ASCII control characters other than those with \-letter escapes. */
|
||||
|
||||
#if C_CTYPE_ASCII
|
||||
# define _C_CTYPE_OTHER_CNTRL \
|
||||
case '\x00': case '\x01': case '\x02': case '\x03': \
|
||||
case '\x04': case '\x05': case '\x06': case '\x0e': \
|
||||
case '\x0f': case '\x10': case '\x11': case '\x12': \
|
||||
case '\x13': case '\x14': case '\x15': case '\x16': \
|
||||
case '\x17': case '\x18': case '\x19': case '\x1a': \
|
||||
case '\x1b': case '\x1c': case '\x1d': case '\x1e': \
|
||||
case '\x1f': case '\x7f'
|
||||
#else
|
||||
/* Use EBCDIC code page 1047's assignments for ASCII control chars;
|
||||
assume all EBCDIC code pages agree about these assignments. */
|
||||
# define _C_CTYPE_OTHER_CNTRL \
|
||||
case '\x00': case '\x01': case '\x02': case '\x03': \
|
||||
case '\x07': case '\x0e': case '\x0f': case '\x10': \
|
||||
case '\x11': case '\x12': case '\x13': case '\x18': \
|
||||
case '\x19': case '\x1c': case '\x1d': case '\x1e': \
|
||||
case '\x1f': case '\x26': case '\x27': case '\x2d': \
|
||||
case '\x2e': case '\x32': case '\x37': case '\x3c': \
|
||||
case '\x3d': case '\x3f'
|
||||
#endif
|
||||
|
||||
/* Cases for lowercase hex letters, and lowercase letters, all offset by N. */
|
||||
|
||||
#define _C_CTYPE_LOWER_A_THRU_F_N(N) \
|
||||
case 'a' + (N): case 'b' + (N): case 'c' + (N): case 'd' + (N): \
|
||||
case 'e' + (N): case 'f' + (N)
|
||||
#define _C_CTYPE_LOWER_N(N) \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N(N): \
|
||||
case 'g' + (N): case 'h' + (N): case 'i' + (N): case 'j' + (N): \
|
||||
case 'k' + (N): case 'l' + (N): case 'm' + (N): case 'n' + (N): \
|
||||
case 'o' + (N): case 'p' + (N): case 'q' + (N): case 'r' + (N): \
|
||||
case 's' + (N): case 't' + (N): case 'u' + (N): case 'v' + (N): \
|
||||
case 'w' + (N): case 'x' + (N): case 'y' + (N): case 'z' + (N)
|
||||
|
||||
/* Cases for hex letters, digits, lower, punct, and upper. */
|
||||
|
||||
#define _C_CTYPE_A_THRU_F \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N (0): \
|
||||
_C_CTYPE_LOWER_A_THRU_F_N ('A' - 'a')
|
||||
#define _C_CTYPE_DIGIT \
|
||||
case '0': case '1': case '2': case '3': \
|
||||
case '4': case '5': case '6': case '7': \
|
||||
case '8': case '9'
|
||||
#define _C_CTYPE_LOWER _C_CTYPE_LOWER_N (0)
|
||||
#define _C_CTYPE_PUNCT \
|
||||
case '!': case '"': case '#': case '$': \
|
||||
case '%': case '&': case '\'': case '(': \
|
||||
case ')': case '*': case '+': case ',': \
|
||||
case '-': case '.': case '/': case ':': \
|
||||
case ';': case '<': case '=': case '>': \
|
||||
case '?': case '@': case '[': case '\\': \
|
||||
case ']': case '^': case '_': case '`': \
|
||||
case '{': case '|': case '}': case '~'
|
||||
#define _C_CTYPE_UPPER _C_CTYPE_LOWER_N ('A' - 'a')
|
||||
|
||||
|
||||
/* Function definitions. */
|
||||
|
||||
/* Unlike the functions in <ctype.h>, which require an argument in the range
|
||||
of the 'unsigned char' type, the functions here operate on values that are
|
||||
in the 'unsigned char' range or in the 'char' range. In other words,
|
||||
when you have a 'char' value, you need to cast it before using it as
|
||||
argument to a <ctype.h> function:
|
||||
|
||||
const char *s = ...;
|
||||
if (isalpha ((unsigned char) *s)) ...
|
||||
|
||||
but you don't need to cast it for the functions defined in this file:
|
||||
|
||||
const char *s = ...;
|
||||
if (c_isalpha (*s)) ...
|
||||
*/
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isalnum (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isalpha (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* The function isascii is not locale dependent.
|
||||
Its use in EBCDIC is questionable. */
|
||||
C_CTYPE_INLINE bool
|
||||
c_isascii (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
_C_CTYPE_CNTRL:
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isblank (int c)
|
||||
{
|
||||
return c == ' ' || c == '\t';
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_iscntrl (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_CNTRL:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isdigit (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isgraph (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_islower (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isprint (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ':
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_LOWER:
|
||||
_C_CTYPE_PUNCT:
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_ispunct (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_PUNCT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isspace (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case ' ': case '\t': case '\n': case '\v': case '\f': case '\r':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isupper (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_UPPER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE bool
|
||||
c_isxdigit (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_DIGIT:
|
||||
_C_CTYPE_A_THRU_F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE int
|
||||
c_tolower (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_UPPER:
|
||||
return c - 'A' + 'a';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
C_CTYPE_INLINE int
|
||||
c_toupper (int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
_C_CTYPE_LOWER:
|
||||
return c - 'a' + 'A';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
_GL_INLINE_HEADER_END
|
||||
|
||||
#endif /* C_CTYPE_H */
|
|
@ -1,56 +0,0 @@
|
|||
/* Case-insensitive string comparison functions in C locale.
|
||||
Copyright (C) 1995-1996, 2001, 2003, 2005, 2009-2020 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef C_STRCASE_H
|
||||
#define C_STRCASE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* The functions defined in this file assume the "C" locale and a character
|
||||
set without diacritics (ASCII-US or EBCDIC-US or something like that).
|
||||
Even if the "C" locale on a particular system is an extension of the ASCII
|
||||
character set (like on BeOS, where it is UTF-8, or on AmigaOS, where it
|
||||
is ISO-8859-1), the functions in this file recognize only the ASCII
|
||||
characters. More precisely, one of the string arguments must be an ASCII
|
||||
string; the other one can also contain non-ASCII characters (but then
|
||||
the comparison result will be nonzero). */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
||||
than S2. */
|
||||
extern int c_strcasecmp (const char *s1, const char *s2) _GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Compare no more than N characters of strings S1 and S2, ignoring case,
|
||||
returning less than, equal to or greater than zero if S1 is
|
||||
lexicographically less than, equal to or greater than S2. */
|
||||
extern int c_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* C_STRCASE_H */
|
|
@ -1,56 +0,0 @@
|
|||
/* c-strcasecmp.c -- case insensitive string comparator in C locale
|
||||
Copyright (C) 1998-1999, 2005-2006, 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
int
|
||||
c_strcasecmp (const char *s1, const char *s2)
|
||||
{
|
||||
register const unsigned char *p1 = (const unsigned char *) s1;
|
||||
register const unsigned char *p2 = (const unsigned char *) s2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = c_tolower (*p1);
|
||||
c2 = c_tolower (*p2);
|
||||
|
||||
if (c1 == '\0')
|
||||
break;
|
||||
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
if (UCHAR_MAX <= INT_MAX)
|
||||
return c1 - c2;
|
||||
else
|
||||
/* On machines where 'char' and 'int' are types of the same size, the
|
||||
difference of two 'unsigned char' values - including the sign bit -
|
||||
doesn't fit in an 'int'. */
|
||||
return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
|
||||
}
|
|
@ -1,181 +0,0 @@
|
|||
/* Optimized case-insensitive string comparison in C locale.
|
||||
Copyright (C) 2001-2002, 2007, 2009-2020 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>. */
|
||||
|
||||
#include "c-strcase.h"
|
||||
#include "c-ctype.h"
|
||||
|
||||
/* STRCASEEQ allows to optimize string comparison with a small literal string.
|
||||
STRCASEEQ (s, "UTF-8", 'U','T','F','-','8',0,0,0,0)
|
||||
is semantically equivalent to
|
||||
c_strcasecmp (s, "UTF-8") == 0
|
||||
just faster. */
|
||||
|
||||
/* Help GCC to generate good code for string comparisons with
|
||||
immediate strings. */
|
||||
#if defined (__GNUC__) && defined (__OPTIMIZE__)
|
||||
|
||||
/* Case insensitive comparison of ASCII characters. */
|
||||
# if C_CTYPE_ASCII
|
||||
# define CASEEQ(other,upper) \
|
||||
(c_isupper (upper) ? ((other) & ~0x20) == (upper) : (other) == (upper))
|
||||
# else
|
||||
# define CASEEQ(other,upper) \
|
||||
(c_toupper (other) == (upper))
|
||||
# endif
|
||||
|
||||
static inline int
|
||||
strcaseeq9 (const char *s1, const char *s2)
|
||||
{
|
||||
return c_strcasecmp (s1 + 9, s2 + 9) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq8 (const char *s1, const char *s2, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[8], s28))
|
||||
{
|
||||
if (s28 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq9 (s1, s2);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq7 (const char *s1, const char *s2, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[7], s27))
|
||||
{
|
||||
if (s27 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq8 (s1, s2, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq6 (const char *s1, const char *s2, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[6], s26))
|
||||
{
|
||||
if (s26 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq7 (s1, s2, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[5], s25))
|
||||
{
|
||||
if (s25 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq6 (s1, s2, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[4], s24))
|
||||
{
|
||||
if (s24 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq5 (s1, s2, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[3], s23))
|
||||
{
|
||||
if (s23 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq4 (s1, s2, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[2], s22))
|
||||
{
|
||||
if (s22 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq3 (s1, s2, s23, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[1], s21))
|
||||
{
|
||||
if (s21 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
strcaseeq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
|
||||
{
|
||||
if (CASEEQ (s1[0], s20))
|
||||
{
|
||||
if (s20 == 0)
|
||||
return 1;
|
||||
else
|
||||
return strcaseeq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
|
||||
strcaseeq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28)
|
||||
|
||||
#else
|
||||
|
||||
#define STRCASEEQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
|
||||
(c_strcasecmp (s1, s2) == 0)
|
||||
|
||||
#endif
|
|
@ -1,56 +0,0 @@
|
|||
/* c-strncasecmp.c -- case insensitive string comparator in C locale
|
||||
Copyright (C) 1998-1999, 2005-2006, 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "c-strcase.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "c-ctype.h"
|
||||
|
||||
int
|
||||
c_strncasecmp (const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
register const unsigned char *p1 = (const unsigned char *) s1;
|
||||
register const unsigned char *p2 = (const unsigned char *) s2;
|
||||
unsigned char c1, c2;
|
||||
|
||||
if (p1 == p2 || n == 0)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
c1 = c_tolower (*p1);
|
||||
c2 = c_tolower (*p2);
|
||||
|
||||
if (--n == 0 || c1 == '\0')
|
||||
break;
|
||||
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
if (UCHAR_MAX <= INT_MAX)
|
||||
return c1 - c2;
|
||||
else
|
||||
/* On machines where 'char' and 'int' are types of the same size, the
|
||||
difference of two 'unsigned char' values - including the sign bit -
|
||||
doesn't fit in an 'int'. */
|
||||
return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
|
||||
}
|
|
@ -1,514 +0,0 @@
|
|||
/* Copyright (C) 1992-2020 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _SYS_CDEFS_H
|
||||
#define _SYS_CDEFS_H 1
|
||||
|
||||
/* We are almost always included from features.h. */
|
||||
#ifndef _FEATURES_H
|
||||
# include <features.h>
|
||||
#endif
|
||||
|
||||
/* The GNU libc does not support any K&R compilers or the traditional mode
|
||||
of ISO C compilers anymore. Check for some of the combinations not
|
||||
anymore supported. */
|
||||
#if defined __GNUC__ && !defined __STDC__
|
||||
# error "You need a ISO C conforming compiler to use the glibc headers"
|
||||
#endif
|
||||
|
||||
/* Some user header file might have defined this before. */
|
||||
#undef __P
|
||||
#undef __PMT
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/* All functions, except those with callbacks or those that
|
||||
synchronize memory, are leaf functions. */
|
||||
# if __GNUC_PREREQ (4, 6) && !defined _LIBC
|
||||
# define __LEAF , __leaf__
|
||||
# define __LEAF_ATTR __attribute__ ((__leaf__))
|
||||
# else
|
||||
# define __LEAF
|
||||
# define __LEAF_ATTR
|
||||
# endif
|
||||
|
||||
/* GCC can always grok prototypes. For C++ programs we add throw()
|
||||
to help it optimize the function calls. But this works only with
|
||||
gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions
|
||||
as non-throwing using a function attribute since programs can use
|
||||
the -fexceptions options for C code as well. */
|
||||
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
|
||||
# define __THROW __attribute__ ((__nothrow__ __LEAF))
|
||||
# define __THROWNL __attribute__ ((__nothrow__))
|
||||
# define __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
|
||||
# define __NTHNL(fct) __attribute__ ((__nothrow__)) fct
|
||||
# else
|
||||
# if defined __cplusplus && __GNUC_PREREQ (2,8)
|
||||
# define __THROW throw ()
|
||||
# define __THROWNL throw ()
|
||||
# define __NTH(fct) __LEAF_ATTR fct throw ()
|
||||
# define __NTHNL(fct) fct throw ()
|
||||
# else
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
# define __NTH(fct) fct
|
||||
# define __NTHNL(fct) fct
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else /* Not GCC. */
|
||||
|
||||
# if (defined __cplusplus \
|
||||
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
|
||||
# define __inline inline
|
||||
# else
|
||||
# define __inline /* No inline functions. */
|
||||
# endif
|
||||
|
||||
# define __THROW
|
||||
# define __THROWNL
|
||||
# define __NTH(fct) fct
|
||||
|
||||
#endif /* GCC. */
|
||||
|
||||
/* Compilers that are not clang may object to
|
||||
#if defined __clang__ && __has_extension(...)
|
||||
even though they do not need to evaluate the right-hand side of the &&. */
|
||||
#if defined __clang__ && defined __has_extension
|
||||
# define __glibc_clang_has_extension(ext) __has_extension (ext)
|
||||
#else
|
||||
# define __glibc_clang_has_extension(ext) 0
|
||||
#endif
|
||||
|
||||
/* These two macros are not used in glibc anymore. They are kept here
|
||||
only because some other projects expect the macros to be defined. */
|
||||
#define __P(args) args
|
||||
#define __PMT(args) args
|
||||
|
||||
/* For these things, GCC behaves the ANSI way normally,
|
||||
and the non-ANSI way under -traditional. */
|
||||
|
||||
#define __CONCAT(x,y) x ## y
|
||||
#define __STRING(x) #x
|
||||
|
||||
/* This is not a typedef so `const __ptr_t' does the right thing. */
|
||||
#define __ptr_t void *
|
||||
|
||||
|
||||
/* C++ needs to know that types and declarations are C, not C++. */
|
||||
#ifdef __cplusplus
|
||||
# define __BEGIN_DECLS extern "C" {
|
||||
# define __END_DECLS }
|
||||
#else
|
||||
# define __BEGIN_DECLS
|
||||
# define __END_DECLS
|
||||
#endif
|
||||
|
||||
|
||||
/* Fortify support. */
|
||||
#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
|
||||
#define __bos0(ptr) __builtin_object_size (ptr, 0)
|
||||
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __warndecl(name, msg) \
|
||||
extern void name (void) __attribute__((__warning__ (msg)))
|
||||
# define __warnattr(msg) __attribute__((__warning__ (msg)))
|
||||
# define __errordecl(name, msg) \
|
||||
extern void name (void) __attribute__((__error__ (msg)))
|
||||
#else
|
||||
# define __warndecl(name, msg) extern void name (void)
|
||||
# define __warnattr(msg)
|
||||
# define __errordecl(name, msg) extern void name (void)
|
||||
#endif
|
||||
|
||||
/* Support for flexible arrays.
|
||||
Headers that should use flexible arrays only if they're "real"
|
||||
(e.g. only if they won't affect sizeof()) should test
|
||||
#if __glibc_c99_flexarr_available. */
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __HP_cc
|
||||
# define __flexarr []
|
||||
# define __glibc_c99_flexarr_available 1
|
||||
#elif __GNUC_PREREQ (2,97)
|
||||
/* GCC 2.97 supports C99 flexible array members as an extension,
|
||||
even when in C89 mode or compiling C++ (any version). */
|
||||
# define __flexarr []
|
||||
# define __glibc_c99_flexarr_available 1
|
||||
#elif defined __GNUC__
|
||||
/* Pre-2.97 GCC did not support C99 flexible arrays but did have
|
||||
an equivalent extension with slightly different notation. */
|
||||
# define __flexarr [0]
|
||||
# define __glibc_c99_flexarr_available 1
|
||||
#else
|
||||
/* Some other non-C99 compiler. Approximate with [1]. */
|
||||
# define __flexarr [1]
|
||||
# define __glibc_c99_flexarr_available 0
|
||||
#endif
|
||||
|
||||
|
||||
/* __asm__ ("xyz") is used throughout the headers to rename functions
|
||||
at the assembly language level. This is wrapped by the __REDIRECT
|
||||
macro, in order to support compilers that can do this some other
|
||||
way. When compilers don't support asm-names at all, we have to do
|
||||
preprocessor tricks instead (which don't have exactly the right
|
||||
semantics, but it's the best we can do).
|
||||
|
||||
Example:
|
||||
int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
|
||||
# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
|
||||
# ifdef __cplusplus
|
||||
# define __REDIRECT_NTH(name, proto, alias) \
|
||||
name proto __THROW __asm__ (__ASMNAME (#alias))
|
||||
# define __REDIRECT_NTHNL(name, proto, alias) \
|
||||
name proto __THROWNL __asm__ (__ASMNAME (#alias))
|
||||
# else
|
||||
# define __REDIRECT_NTH(name, proto, alias) \
|
||||
name proto __asm__ (__ASMNAME (#alias)) __THROW
|
||||
# define __REDIRECT_NTHNL(name, proto, alias) \
|
||||
name proto __asm__ (__ASMNAME (#alias)) __THROWNL
|
||||
# endif
|
||||
# define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
|
||||
# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
|
||||
|
||||
/*
|
||||
#elif __SOME_OTHER_COMPILER__
|
||||
|
||||
# define __REDIRECT(name, proto, alias) name proto; \
|
||||
_Pragma("let " #name " = " #alias)
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* GCC has various useful declarations that can be made with the
|
||||
`__attribute__' syntax. All of the ways we use this do fine if
|
||||
they are omitted for compilers that don't understand it. */
|
||||
#if !defined __GNUC__ || __GNUC__ < 2
|
||||
# define __attribute__(xyz) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.96 development the `malloc' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96)
|
||||
# define __attribute_malloc__ __attribute__ ((__malloc__))
|
||||
#else
|
||||
# define __attribute_malloc__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Tell the compiler which arguments to an allocation function
|
||||
indicate the size of the allocation. */
|
||||
#if __GNUC_PREREQ (4, 3)
|
||||
# define __attribute_alloc_size__(params) \
|
||||
__attribute__ ((__alloc_size__ params))
|
||||
#else
|
||||
# define __attribute_alloc_size__(params) /* Ignore. */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.96 development the `pure' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (2,96)
|
||||
# define __attribute_pure__ __attribute__ ((__pure__))
|
||||
#else
|
||||
# define __attribute_pure__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* This declaration tells the compiler that the value is constant. */
|
||||
#if __GNUC_PREREQ (2,5)
|
||||
# define __attribute_const__ __attribute__ ((__const__))
|
||||
#else
|
||||
# define __attribute_const__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 3.1 development the `used' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings. */
|
||||
#if __GNUC_PREREQ (3,1)
|
||||
# define __attribute_used__ __attribute__ ((__used__))
|
||||
# define __attribute_noinline__ __attribute__ ((__noinline__))
|
||||
#else
|
||||
# define __attribute_used__ __attribute__ ((__unused__))
|
||||
# define __attribute_noinline__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Since version 3.2, gcc allows marking deprecated functions. */
|
||||
#if __GNUC_PREREQ (3,2)
|
||||
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
|
||||
#else
|
||||
# define __attribute_deprecated__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Since version 4.5, gcc also allows one to specify the message printed
|
||||
when a deprecated function is used. clang claims to be gcc 4.2, but
|
||||
may also support this feature. */
|
||||
#if __GNUC_PREREQ (4,5) || \
|
||||
__glibc_clang_has_extension (__attribute_deprecated_with_message__)
|
||||
# define __attribute_deprecated_msg__(msg) \
|
||||
__attribute__ ((__deprecated__ (msg)))
|
||||
#else
|
||||
# define __attribute_deprecated_msg__(msg) __attribute_deprecated__
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.8 development the `format_arg' attribute
|
||||
for functions was introduced. We don't want to use it unconditionally
|
||||
(although this would be possible) since it generates warnings.
|
||||
If several `format_arg' attributes are given for the same function, in
|
||||
gcc-3.0 and older, all but the last one are ignored. In newer gccs,
|
||||
all designated arguments are considered. */
|
||||
#if __GNUC_PREREQ (2,8)
|
||||
# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
|
||||
#else
|
||||
# define __attribute_format_arg__(x) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* At some point during the gcc 2.97 development the `strfmon' format
|
||||
attribute for functions was introduced. We don't want to use it
|
||||
unconditionally (although this would be possible) since it
|
||||
generates warnings. */
|
||||
#if __GNUC_PREREQ (2,97)
|
||||
# define __attribute_format_strfmon__(a,b) \
|
||||
__attribute__ ((__format__ (__strfmon__, a, b)))
|
||||
#else
|
||||
# define __attribute_format_strfmon__(a,b) /* Ignore */
|
||||
#endif
|
||||
|
||||
/* The nonnull function attribute marks pointer parameters that
|
||||
must not be NULL. Do not define __nonnull if it is already defined,
|
||||
for portability when this file is used in Gnulib. */
|
||||
#ifndef __nonnull
|
||||
# if __GNUC_PREREQ (3,3)
|
||||
# define __nonnull(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define __nonnull(params)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If fortification mode, we warn about unused results of certain
|
||||
function calls which can lead to problems. */
|
||||
#if __GNUC_PREREQ (3,4)
|
||||
# define __attribute_warn_unused_result__ \
|
||||
__attribute__ ((__warn_unused_result__))
|
||||
# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
|
||||
# define __wur __attribute_warn_unused_result__
|
||||
# endif
|
||||
#else
|
||||
# define __attribute_warn_unused_result__ /* empty */
|
||||
#endif
|
||||
#ifndef __wur
|
||||
# define __wur /* Ignore */
|
||||
#endif
|
||||
|
||||
/* Forces a function to be always inlined. */
|
||||
#if __GNUC_PREREQ (3,2)
|
||||
/* The Linux kernel defines __always_inline in stddef.h (283d7573), and
|
||||
it conflicts with this definition. Therefore undefine it first to
|
||||
allow either header to be included first. */
|
||||
# undef __always_inline
|
||||
# define __always_inline __inline __attribute__ ((__always_inline__))
|
||||
#else
|
||||
# undef __always_inline
|
||||
# define __always_inline __inline
|
||||
#endif
|
||||
|
||||
/* Associate error messages with the source location of the call site rather
|
||||
than with the source location inside the function. */
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __attribute_artificial__ __attribute__ ((__artificial__))
|
||||
#else
|
||||
# define __attribute_artificial__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
|
||||
inline semantics, unless -fgnu89-inline is used. Using __GNUC_STDC_INLINE__
|
||||
or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
|
||||
older than 4.3 may define these macros and still not guarantee GNU inlining
|
||||
semantics.
|
||||
|
||||
clang++ identifies itself as gcc-4.2, but has support for GNU inlining
|
||||
semantics, that can be checked for by using the __GNUC_STDC_INLINE_ and
|
||||
__GNUC_GNU_INLINE__ macro definitions. */
|
||||
#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \
|
||||
|| (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
|
||||
|| defined __GNUC_GNU_INLINE__)))
|
||||
# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
|
||||
# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
|
||||
# define __extern_always_inline \
|
||||
extern __always_inline __attribute__ ((__gnu_inline__))
|
||||
# else
|
||||
# define __extern_inline extern __inline
|
||||
# define __extern_always_inline extern __always_inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __extern_always_inline
|
||||
# define __fortify_function __extern_always_inline __attribute_artificial__
|
||||
#endif
|
||||
|
||||
/* GCC 4.3 and above allow passing all anonymous arguments of an
|
||||
__extern_always_inline function to some other vararg function. */
|
||||
#if __GNUC_PREREQ (4,3)
|
||||
# define __va_arg_pack() __builtin_va_arg_pack ()
|
||||
# define __va_arg_pack_len() __builtin_va_arg_pack_len ()
|
||||
#endif
|
||||
|
||||
/* It is possible to compile containing GCC extensions even if GCC is
|
||||
run in pedantic mode if the uses are carefully marked using the
|
||||
`__extension__' keyword. But this is not generally available before
|
||||
version 2.8. */
|
||||
#if !__GNUC_PREREQ (2,8)
|
||||
# define __extension__ /* Ignore */
|
||||
#endif
|
||||
|
||||
/* __restrict is known in EGCS 1.2 and above. */
|
||||
#if !__GNUC_PREREQ (2,92)
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __restrict restrict
|
||||
# else
|
||||
# define __restrict /* Ignore */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ISO C99 also allows to declare arrays as non-overlapping. The syntax is
|
||||
array_name[restrict]
|
||||
GCC 3.1 supports this. */
|
||||
#if __GNUC_PREREQ (3,1) && !defined __GNUG__
|
||||
# define __restrict_arr __restrict
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define __restrict_arr /* Not supported in old GCC. */
|
||||
# else
|
||||
# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
|
||||
# define __restrict_arr restrict
|
||||
# else
|
||||
/* Some other non-C99 compiler. */
|
||||
# define __restrict_arr /* Not supported. */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
# define __glibc_unlikely(cond) __builtin_expect ((cond), 0)
|
||||
# define __glibc_likely(cond) __builtin_expect ((cond), 1)
|
||||
#else
|
||||
# define __glibc_unlikely(cond) (cond)
|
||||
# define __glibc_likely(cond) (cond)
|
||||
#endif
|
||||
|
||||
#ifdef __has_attribute
|
||||
# define __glibc_has_attribute(attr) __has_attribute (attr)
|
||||
#else
|
||||
# define __glibc_has_attribute(attr) 0
|
||||
#endif
|
||||
|
||||
#if (!defined _Noreturn \
|
||||
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
|
||||
&& !__GNUC_PREREQ (4,7))
|
||||
# if __GNUC_PREREQ (2,8)
|
||||
# define _Noreturn __attribute__ ((__noreturn__))
|
||||
# else
|
||||
# define _Noreturn
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __GNUC_PREREQ (8, 0)
|
||||
/* Describes a char array whose address can safely be passed as the first
|
||||
argument to strncpy and strncat, as the char array is not necessarily
|
||||
a NUL-terminated string. */
|
||||
# define __attribute_nonstring__ __attribute__ ((__nonstring__))
|
||||
#else
|
||||
# define __attribute_nonstring__
|
||||
#endif
|
||||
|
||||
#if (!defined _Static_assert && !defined __cplusplus \
|
||||
&& (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
|
||||
&& (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
|
||||
# define _Static_assert(expr, diagnostic) \
|
||||
extern int (*__Static_assert_function (void)) \
|
||||
[!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
|
||||
#endif
|
||||
|
||||
/* The #ifndef lets Gnulib avoid including these on non-glibc
|
||||
platforms, where the includes typically do not exist. */
|
||||
#ifndef __WORDSIZE
|
||||
# include <bits/wordsize.h>
|
||||
# include <bits/long-double.h>
|
||||
#endif
|
||||
|
||||
#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
|
||||
# define __LDBL_COMPAT 1
|
||||
# ifdef __REDIRECT
|
||||
# define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
|
||||
# define __LDBL_REDIR(name, proto) \
|
||||
__LDBL_REDIR1 (name, proto, __nldbl_##name)
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)
|
||||
# define __LDBL_REDIR_NTH(name, proto) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __nldbl_##name)
|
||||
# define __LDBL_REDIR1_DECL(name, alias) \
|
||||
extern __typeof (name) name __asm (__ASMNAME (#alias));
|
||||
# define __LDBL_REDIR_DECL(name) \
|
||||
extern __typeof (name) name __asm (__ASMNAME ("__nldbl_" #name));
|
||||
# define __REDIRECT_LDBL(name, proto, alias) \
|
||||
__LDBL_REDIR1 (name, proto, __nldbl_##alias)
|
||||
# define __REDIRECT_NTH_LDBL(name, proto, alias) \
|
||||
__LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)
|
||||
# endif
|
||||
#endif
|
||||
#if !defined __LDBL_COMPAT || !defined __REDIRECT
|
||||
# define __LDBL_REDIR1(name, proto, alias) name proto
|
||||
# define __LDBL_REDIR(name, proto) name proto
|
||||
# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
|
||||
# define __LDBL_REDIR_NTH(name, proto) name proto __THROW
|
||||
# define __LDBL_REDIR_DECL(name)
|
||||
# ifdef __REDIRECT
|
||||
# define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
|
||||
# define __REDIRECT_NTH_LDBL(name, proto, alias) \
|
||||
__REDIRECT_NTH (name, proto, alias)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* __glibc_macro_warning (MESSAGE) issues warning MESSAGE. This is
|
||||
intended for use in preprocessor macros.
|
||||
|
||||
Note: MESSAGE must be a _single_ string; concatenation of string
|
||||
literals is not supported. */
|
||||
#if __GNUC_PREREQ (4,8) || __glibc_clang_prereq (3,5)
|
||||
# define __glibc_macro_warning1(message) _Pragma (#message)
|
||||
# define __glibc_macro_warning(message) \
|
||||
__glibc_macro_warning1 (GCC warning message)
|
||||
#else
|
||||
# define __glibc_macro_warning(msg)
|
||||
#endif
|
||||
|
||||
/* Generic selection (ISO C11) is a C-only feature, available in GCC
|
||||
since version 4.9. Previous versions do not provide generic
|
||||
selection, even though they might set __STDC_VERSION__ to 201112L,
|
||||
when in -std=c11 mode. Thus, we must check for !defined __GNUC__
|
||||
when testing __STDC_VERSION__ for generic selection support.
|
||||
On the other hand, Clang also defines __GNUC__, so a clang-specific
|
||||
check is required to enable the use of generic selection. */
|
||||
#if !defined __cplusplus \
|
||||
&& (__GNUC_PREREQ (4, 9) \
|
||||
|| __glibc_clang_has_extension (c_generic_selections) \
|
||||
|| (!defined __GNUC__ && defined __STDC_VERSION__ \
|
||||
&& __STDC_VERSION__ >= 201112L))
|
||||
# define __HAVE_GENERIC_SELECTION 1
|
||||
#else
|
||||
# define __HAVE_GENERIC_SELECTION 0
|
||||
#endif
|
||||
|
||||
#endif /* sys/cdefs.h */
|
|
@ -1,78 +0,0 @@
|
|||
/* Close a stream, with nicer error checking than fclose's.
|
||||
|
||||
Copyright (C) 1998-2002, 2004, 2006-2020 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/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "close-stream.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "fpending.h"
|
||||
|
||||
#if USE_UNLOCKED_IO
|
||||
# include "unlocked-io.h"
|
||||
#endif
|
||||
|
||||
/* Close STREAM. Return 0 if successful, EOF (setting errno)
|
||||
otherwise. A failure might set errno to 0 if the error number
|
||||
cannot be determined.
|
||||
|
||||
A failure with errno set to EPIPE may or may not indicate an error
|
||||
situation worth signaling to the user. See the documentation of the
|
||||
close_stdout_set_ignore_EPIPE function for details.
|
||||
|
||||
If a program writes *anything* to STREAM, that program should close
|
||||
STREAM and make sure that it succeeds before exiting. Otherwise,
|
||||
suppose that you go to the extreme of checking the return status
|
||||
of every function that does an explicit write to STREAM. The last
|
||||
printf can succeed in writing to the internal stream buffer, and yet
|
||||
the fclose(STREAM) could still fail (due e.g., to a disk full error)
|
||||
when it tries to write out that buffered data. Thus, you would be
|
||||
left with an incomplete output file and the offending program would
|
||||
exit successfully. Even calling fflush is not always sufficient,
|
||||
since some file systems (NFS and CODA) buffer written/flushed data
|
||||
until an actual close call.
|
||||
|
||||
Besides, it's wasteful to check the return value from every call
|
||||
that writes to STREAM -- just let the internal stream state record
|
||||
the failure. That's what the ferror test is checking below. */
|
||||
|
||||
int
|
||||
close_stream (FILE *stream)
|
||||
{
|
||||
const bool some_pending = (__fpending (stream) != 0);
|
||||
const bool prev_fail = (ferror (stream) != 0);
|
||||
const bool fclose_fail = (fclose (stream) != 0);
|
||||
|
||||
/* Return an error indication if there was a previous failure or if
|
||||
fclose failed, with one exception: ignore an fclose failure if
|
||||
there was no previous error, no data remains to be flushed, and
|
||||
fclose failed with EBADF. That can happen when a program like cp
|
||||
is invoked like this 'cp a b >&-' (i.e., with standard output
|
||||
closed) and doesn't generate any output (hence no previous error
|
||||
and nothing to be flushed). */
|
||||
|
||||
if (prev_fail || (fclose_fail && (some_pending || errno != EBADF)))
|
||||
{
|
||||
if (! fclose_fail)
|
||||
errno = 0;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
#include <stdio.h>
|
||||
int close_stream (FILE *stream);
|
|
@ -1,136 +0,0 @@
|
|||
/* Close standard output and standard error, exiting with a diagnostic on error.
|
||||
|
||||
Copyright (C) 1998-2002, 2004, 2006, 2008-2020 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/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "closeout.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
|
||||
#include "close-stream.h"
|
||||
#include "error.h"
|
||||
#include "exitfail.h"
|
||||
#include "quotearg.h"
|
||||
|
||||
#ifndef __has_feature
|
||||
# define __has_feature(a) false
|
||||
#endif
|
||||
|
||||
#if defined __SANITIZE_ADDRESS__ || __has_feature (address_sanitizer)
|
||||
enum { SANITIZE_ADDRESS = true };
|
||||
#else
|
||||
enum { SANITIZE_ADDRESS = false };
|
||||
#endif
|
||||
|
||||
static const char *file_name;
|
||||
|
||||
/* Set the file name to be reported in the event an error is detected
|
||||
by close_stdout. */
|
||||
void
|
||||
close_stdout_set_file_name (const char *file)
|
||||
{
|
||||
file_name = file;
|
||||
}
|
||||
|
||||
static bool ignore_EPIPE /* = false */;
|
||||
|
||||
/* Specify the reaction to an EPIPE error during the closing of stdout:
|
||||
- If ignore = true, it shall be ignored.
|
||||
- If ignore = false, it shall evoke a diagnostic, along with a nonzero
|
||||
exit status.
|
||||
The default is ignore = false.
|
||||
|
||||
This setting matters only if the SIGPIPE signal is ignored (i.e. its
|
||||
handler set to SIG_IGN) or blocked. Only particular programs need to
|
||||
temporarily ignore SIGPIPE. If SIGPIPE is ignored or blocked because
|
||||
it was ignored or blocked in the parent process when it created the
|
||||
child process, it usually is a bug in the parent process: It is bad
|
||||
practice to have SIGPIPE ignored or blocked while creating a child
|
||||
process.
|
||||
|
||||
EPIPE occurs when writing to a pipe or socket that has no readers now,
|
||||
when SIGPIPE is ignored or blocked.
|
||||
|
||||
The ignore = false setting is suitable for a scenario where it is normally
|
||||
guaranteed that the pipe writer terminates before the pipe reader. In
|
||||
this case, an EPIPE is an indication of a premature termination of the
|
||||
pipe reader and should lead to a diagnostic and a nonzero exit status.
|
||||
|
||||
The ignore = true setting is suitable for a scenario where you don't know
|
||||
ahead of time whether the pipe writer or the pipe reader will terminate
|
||||
first. In this case, an EPIPE is an indication that the pipe writer can
|
||||
stop doing useless write() calls; this is what close_stdout does anyway.
|
||||
EPIPE is part of the normal pipe/socket shutdown protocol in this case,
|
||||
and should not lead to a diagnostic message. */
|
||||
|
||||
void
|
||||
close_stdout_set_ignore_EPIPE (bool ignore)
|
||||
{
|
||||
ignore_EPIPE = ignore;
|
||||
}
|
||||
|
||||
/* Close standard output. On error, issue a diagnostic and _exit
|
||||
with status 'exit_failure'.
|
||||
|
||||
Also close standard error. On error, _exit with status 'exit_failure'.
|
||||
|
||||
Since close_stdout is commonly registered via 'atexit', POSIX
|
||||
and the C standard both say that it should not call 'exit',
|
||||
because the behavior is undefined if 'exit' is called more than
|
||||
once. So it calls '_exit' instead of 'exit'. If close_stdout
|
||||
is registered via atexit before other functions are registered,
|
||||
the other functions can act before this _exit is invoked.
|
||||
|
||||
Applications that use close_stdout should flush any streams
|
||||
other than stdout and stderr before exiting, since the call to
|
||||
_exit will bypass other buffer flushing. Applications should
|
||||
be flushing and closing other streams anyway, to check for I/O
|
||||
errors. Also, applications should not use tmpfile, since _exit
|
||||
can bypass the removal of these files.
|
||||
|
||||
It's important to detect such failures and exit nonzero because many
|
||||
tools (most notably 'make' and other build-management systems) depend
|
||||
on being able to detect failure in other tools via their exit status. */
|
||||
|
||||
void
|
||||
close_stdout (void)
|
||||
{
|
||||
if (close_stream (stdout) != 0
|
||||
&& !(ignore_EPIPE && errno == EPIPE))
|
||||
{
|
||||
char const *write_error = _("write error");
|
||||
if (file_name)
|
||||
error (0, errno, "%s: %s", quotearg_colon (file_name),
|
||||
write_error);
|
||||
else
|
||||
error (0, errno, "%s", write_error);
|
||||
|
||||
_exit (exit_failure);
|
||||
}
|
||||
|
||||
/* Close stderr only if not sanitizing, as sanitizers may report to
|
||||
stderr after this function returns. */
|
||||
if (!SANITIZE_ADDRESS && close_stream (stderr) != 0)
|
||||
_exit (exit_failure);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/* Close standard output and standard error.
|
||||
|
||||
Copyright (C) 1998, 2000, 2003-2004, 2006, 2008-2020 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/>. */
|
||||
|
||||
#ifndef CLOSEOUT_H
|
||||
# define CLOSEOUT_H 1
|
||||
|
||||
# include <stdbool.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
void close_stdout_set_file_name (const char *file);
|
||||
void close_stdout_set_ignore_EPIPE (bool ignore);
|
||||
void close_stdout (void);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
|
@ -1,61 +0,0 @@
|
|||
/* Copy access control list from one file to file. -*- coding: utf-8 -*-
|
||||
|
||||
Copyright (C) 2002-2003, 2005-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "acl.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "quote.h"
|
||||
#include "error.h"
|
||||
#include "gettext.h"
|
||||
#define _(msgid) gettext (msgid)
|
||||
|
||||
|
||||
/* Copy access control lists from one file to another. If SOURCE_DESC is
|
||||
a valid file descriptor, use file descriptor operations, else use
|
||||
filename based operations on SRC_NAME. Likewise for DEST_DESC and
|
||||
DST_NAME.
|
||||
If access control lists are not available, fchmod the target file to
|
||||
MODE. Also sets the non-permission bits of the destination file
|
||||
(S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
|
||||
Return 0 if successful, otherwise output a diagnostic and return a
|
||||
negative error code. */
|
||||
|
||||
int
|
||||
copy_acl (const char *src_name, int source_desc, const char *dst_name,
|
||||
int dest_desc, mode_t mode)
|
||||
{
|
||||
int ret = qcopy_acl (src_name, source_desc, dst_name, dest_desc, mode);
|
||||
switch (ret)
|
||||
{
|
||||
case -2:
|
||||
error (0, errno, "%s", quote (src_name));
|
||||
break;
|
||||
|
||||
case -1:
|
||||
error (0, errno, _("preserving permissions for %s"), quote (dst_name));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -1,505 +0,0 @@
|
|||
/* DO NOT EDIT! GENERATED AUTOMATICALLY! */
|
||||
/* A substitute for ISO C99 <ctype.h>, for platforms on which it is incomplete.
|
||||
|
||||
Copyright (C) 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Written by Bruno Haible. */
|
||||
|
||||
/*
|
||||
* ISO C 99 <ctype.h> for platforms on which it is incomplete.
|
||||
* <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/ctype.h.html>
|
||||
*/
|
||||
|
||||
#ifndef _GL_CTYPE_H
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
|
||||
/* Include the original <ctype.h>. */
|
||||
/* The include_next requires a split double-inclusion guard. */
|
||||
#include_next <ctype.h>
|
||||
|
||||
#ifndef _GL_CTYPE_H
|
||||
#define _GL_CTYPE_H
|
||||
|
||||
/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
|
||||
/* C++ compatible function declaration macros.
|
||||
Copyright (C) 2010-2020 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/>. */
|
||||
|
||||
#ifndef _GL_CXXDEFS_H
|
||||
#define _GL_CXXDEFS_H
|
||||
|
||||
/* Begin/end the GNULIB_NAMESPACE namespace. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
|
||||
# define _GL_END_NAMESPACE }
|
||||
#else
|
||||
# define _GL_BEGIN_NAMESPACE
|
||||
# define _GL_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
/* The three most frequent use cases of these macros are:
|
||||
|
||||
* For providing a substitute for a function that is missing on some
|
||||
platforms, but is declared and works fine on the platforms on which
|
||||
it exists:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if !@HAVE_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on all platforms,
|
||||
but is broken/insufficient and needs to be replaced on some platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on some platforms
|
||||
but is broken/insufficient and needs to be replaced on some of them and
|
||||
is additionally either missing or undeclared on some other platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* _GL_EXTERN_C declaration;
|
||||
performs the declaration with C linkage. */
|
||||
#if defined __cplusplus
|
||||
# define _GL_EXTERN_C extern "C"
|
||||
#else
|
||||
# define _GL_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
|
||||
declares a replacement function, named rpl_func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
|
||||
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
|
||||
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
|
||||
|
||||
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
|
||||
declares the system function, named func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype func parameters_and_attributes
|
||||
|
||||
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping rpl_func in an object with an inline conversion operator
|
||||
avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::rpl_func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
|
||||
except that the C function rpl_func may have a slightly different
|
||||
declaration. A cast is used to silence the "invalid conversion" error
|
||||
that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::rpl_func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to the system provided function func, if GNULIB_NAMESPACE
|
||||
is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
|
||||
Wrapping func in an object with an inline conversion operator
|
||||
avoids a reference to func unless GNULIB_NAMESPACE::func is
|
||||
actually used in the program. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return ::func; \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function func may have a slightly different declaration.
|
||||
A cast is used to silence the "invalid conversion" error that would
|
||||
otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>(::func); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function is picked among a set of overloaded functions,
|
||||
namely the one with rettype2 and parameters2. Two consecutive casts
|
||||
are used to silence the "cannot find a match" and "invalid conversion"
|
||||
errors that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* The outer cast must be a reinterpret_cast.
|
||||
The inner cast: When the function is defined as a set of overloaded
|
||||
functions, it works as a static_cast<>, choosing the designated variant.
|
||||
When the function is defined as a single variant, it works as a
|
||||
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static const struct _gl_ ## func ## _wrapper \
|
||||
{ \
|
||||
typedef rettype (*type) parameters; \
|
||||
\
|
||||
inline operator type () const \
|
||||
{ \
|
||||
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
|
||||
} \
|
||||
} func = {}; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN (func);
|
||||
causes a warning to be emitted when ::func is used but not when
|
||||
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
|
||||
variants. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN_1(func,namespace) \
|
||||
_GL_CXXALIASWARN_2 (func, namespace)
|
||||
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_WARN_ON_USE (func, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
|
||||
causes a warning to be emitted when the given overloaded variant of ::func
|
||||
is used but not when GNULIB_NAMESPACE::func is used. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
|
||||
GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
|
||||
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
#endif /* _GL_CXXDEFS_H */
|
||||
|
||||
/* The definition of _GL_WARN_ON_USE is copied here. */
|
||||
/* A C macro for emitting warnings if a function is used.
|
||||
Copyright (C) 2010-2020 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/>. */
|
||||
|
||||
/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
|
||||
for FUNCTION which will then trigger a compiler warning containing
|
||||
the text of "literal string" anywhere that function is called, if
|
||||
supported by the compiler. If the compiler does not support this
|
||||
feature, the macro expands to an unused extern declaration.
|
||||
|
||||
_GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
|
||||
attribute used in _GL_WARN_ON_USE. If the compiler does not support
|
||||
this feature, it expands to empty.
|
||||
|
||||
These macros are useful for marking a function as a potential
|
||||
portability trap, with the intent that "literal string" include
|
||||
instructions on the replacement function that should be used
|
||||
instead.
|
||||
_GL_WARN_ON_USE is for functions with 'extern' linkage.
|
||||
_GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
|
||||
linkage.
|
||||
|
||||
However, one of the reasons that a function is a portability trap is
|
||||
if it has the wrong signature. Declaring FUNCTION with a different
|
||||
signature in C is a compilation error, so this macro must use the
|
||||
same type as any existing declaration so that programs that avoid
|
||||
the problematic FUNCTION do not fail to compile merely because they
|
||||
included a header that poisoned the function. But this implies that
|
||||
_GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
|
||||
have a declaration. Use of this macro implies that there must not
|
||||
be any other macro hiding the declaration of FUNCTION; but
|
||||
undefining FUNCTION first |