Browse Source

Testing musl support, disabled by default

Imported multiple utilities from ubase to replace util-linux utils
Only build utilities from util-linux that can't be had elsewhere
odin
Nathan Fisher 9 months ago
parent
commit
f014b6d01c
  1. 12
      Makefile
  2. 19
      distfiles/Makefile
  3. 8
      include/mk/src-config.mk
  4. 8
      include/mk/targets.mk
  5. 5
      include/mk/versions.mk
  6. 3
      toolchain/Makefile
  7. 3
      toolchain/gcc-pass2/Makefile
  8. 13
      toolchain/musl/Makefile
  9. 6
      world/Makefile
  10. 9
      world/argp-standalone/Makefile
  11. 3
      world/argp-standalone/src/acconfig.h
  12. 25
      world/argp-standalone/src/argp-ba.c
  13. 31
      world/argp-standalone/src/argp-eexst.c
  14. 433
      world/argp-standalone/src/argp-fmtstream.c
  15. 263
      world/argp-standalone/src/argp-fmtstream.h
  16. 1890
      world/argp-standalone/src/argp-help.c
  17. 149
      world/argp-standalone/src/argp-namefrob.h
  18. 941
      world/argp-standalone/src/argp-parse.c
  19. 24
      world/argp-standalone/src/argp-pv.c
  20. 31
      world/argp-standalone/src/argp-pvh.c
  21. 212
      world/argp-standalone/src/argp-test.c
  22. 582
      world/argp-standalone/src/argp.h
  23. 18
      world/argp-standalone/src/mempcpy.c
  24. 21
      world/argp-standalone/src/strchrnul.c
  25. 31
      world/argp-standalone/src/strndup.c
  26. 1
      world/bin/blkdiscard/LICENSE
  27. 6
      world/bin/blkdiscard/Makefile
  28. 12
      world/bin/blkdiscard/man/blkdiscard.8
  29. 48
      world/bin/blkdiscard/src/blkdiscard.c
  30. 1
      world/bin/chgrp/LICENSE
  31. 6
      world/bin/chgrp/Makefile
  32. 75
      world/bin/chgrp/src/chgrp.c
  33. 1
      world/bin/chvt/LICENSE
  34. 6
      world/bin/chvt/Makefile
  35. 15
      world/bin/chvt/man/chvt.1
  36. 67
      world/bin/chvt/src/chvt.c
  37. 1
      world/bin/clear/LICENSE
  38. 6
      world/bin/clear/Makefile
  39. 11
      world/bin/clear/man/clear.1
  40. 23
      world/bin/clear/src/clear.c
  41. 1
      world/bin/cols/LICENSE
  42. 6
      world/bin/cols/Makefile
  43. 56
      world/bin/cols/man/cols.1
  44. 98
      world/bin/cols/src/cols.c
  45. 1
      world/bin/cron/LICENSE
  46. 6
      world/bin/cron/Makefile
  47. 23
      world/bin/cron/man/cron.1
  48. 566
      world/bin/cron/src/cron.c
  49. 1
      world/bin/ctrlaltdel/LICENSE
  50. 6
      world/bin/ctrlaltdel/Makefile
  51. 31
      world/bin/ctrlaltdel/man/ctrlaltdel.8
  52. 42
      world/bin/ctrlaltdel/src/ctrlaltdel.c
  53. 1
      world/bin/fallocate/LICENSE
  54. 6
      world/bin/fallocate/Makefile
  55. 33
      world/bin/fallocate/man/fallocate.1
  56. 55
      world/bin/fallocate/src/fallocate.c
  57. 1
      world/bin/freeramdisk/LICENSE
  58. 6
      world/bin/freeramdisk/Makefile
  59. 13
      world/bin/freeramdisk/man/freeramdisk.8
  60. 39
      world/bin/freeramdisk/src/freeramdisk.c
  61. 1
      world/bin/fsfreeze/LICENSE
  62. 6
      world/bin/fsfreeze/Makefile
  63. 33
      world/bin/fsfreeze/man/fsfreeze.8
  64. 54
      world/bin/fsfreeze/src/fsfreeze.c
  65. 1
      world/bin/getty/LICENSE
  66. 6
      world/bin/getty/Makefile
  67. 22
      world/bin/getty/man/getty.8
  68. 140
      world/bin/getty/src/getty.c
  69. 1
      world/bin/halt/LICENSE
  70. 6
      world/bin/halt/Makefile
  71. 21
      world/bin/halt/man/halt.8
  72. 51
      world/bin/halt/src/halt.c
  73. 1
      world/bin/hwclock/LICENSE
  74. 6
      world/bin/hwclock/Makefile
  75. 31
      world/bin/hwclock/man/hwclock.8
  76. 159
      world/bin/hwclock/src/hwclock.c
  77. 1
      world/bin/insmod/LICENSE
  78. 6
      world/bin/insmod/Makefile
  79. 18
      world/bin/insmod/man/insmod.8
  80. 69
      world/bin/insmod/src/insmod.c
  81. 1
      world/bin/kill/LICENSE
  82. 6
      world/bin/kill/Makefile
  83. 47
      world/bin/kill/man/kill.1
  84. 130
      world/bin/kill/src/kill.c
  85. 1
      world/bin/killall5/LICENSE
  86. 6
      world/bin/killall5/Makefile
  87. 31
      world/bin/killall5/man/killall5.8
  88. 111
      world/bin/killall5/src/killall5.c
  89. 1
      world/bin/lastlog/LICENSE
  90. 6
      world/bin/lastlog/Makefile
  91. 18
      world/bin/lastlog/man/lastlog.8
  92. 78
      world/bin/lastlog/src/lastlog.c
  93. 1
      world/bin/lsmod/LICENSE
  94. 6
      world/bin/lsmod/Makefile
  95. 13
      world/bin/lsmod/man/lsmod.8
  96. 67
      world/bin/lsmod/src/lsmod.c
  97. 1
      world/bin/lsusb/LICENSE
  98. 6
      world/bin/lsusb/Makefile
  99. 13
      world/bin/lsusb/man/lsusb.8
  100. 58
      world/bin/lsusb/src/lsusb.c

12
Makefile

@ -84,8 +84,7 @@ $(build)/.skeleton.built: | $(dirs)
install -dv -m 1777 $(build)/tmp $(build)/var/tmp
[ -h $(build)/var/run ] || ln -sv /run $(build)/var/run
[ -h $(build)/var/lock ] || ln -sv /run/lock $(build)/var/lock
[ -c $(build)/dev/console ] || su -c "mknod -m 600 $(build)/dev/console c 5 1"
[ -c $(build)/dev/null ] || su -c "mknod -m 666 $(build)/dev/null c 1 3"
#su -c "mknod -m 600 $(build)/dev/console c 5 1 && mknod -m 666 $(build)/dev/null c 1 3"
touch $@
$(plists): $(build)/.built
@ -135,11 +134,14 @@ remove-toolchain:
$(MAKE) -C toolchain remove
clean:
$(MAKE) -C world clean
$(MAKE) -C toolchain clean
rm -rf build/src-*
rm -rf build/obj-*
distclean:
$(MAKE) -C world clean
$(MAKE) -C toolchain clean
rm -rf build/*
rm -rf build/.built
rm -rf build/.skeleton.built
rm -rf build/.stripped
.PHONY: clean

19
distfiles/Makefile

@ -12,6 +12,7 @@ skarnet = https://skarnet.org/software
distfiles = \
acl-${acl_version}.tar.gz \
$(argp-standalone_version).tar.gz \
attr-${attr_version}.tar.gz \
autoconf-${autoconf_version}.tar.xz \
automake-${automake_version}.tar.xz \
@ -69,6 +70,8 @@ man-pages-${man-pages_version}.tar.xz \
meson-${meson_version}.tar.gz \
mpc-${mpc_version}.tar.gz \
mpfr-${mpfr_version}.tar.xz \
musl-$(musl_version).tar.gz \
musl-fts-$(musl-fts_version).tar.gz \
ncurses-${ncurses_version}.tar.gz \
netbsd-curses-${netbsd-curses_version}.tar.xz \
ninja-${ninja_version}.tar.gz \
@ -111,6 +114,11 @@ acl: acl-${acl_version}.tar.gz
acl-${acl_version}.tar.gz:
wget -c ${savannah}/acl/$@
argp-standalone: $(argp-standalone_version).tar.gz
$(argp-standalone_version).tar.gz:
wget -c $(github)/ericonr/argp-standalone/archive/$@
attr: attr-${attr_version}.tar.gz
attr-${attr_version}.tar.gz:
@ -406,6 +414,17 @@ mpfr: mpfr-${mpfr_version}.tar.xz
mpfr-${mpfr_version}.tar.xz:
wget -c http://www.mpfr.org/mpfr-${mpfr_version}/$@
musl: musl-$(musl_version).tar.gz
musl-$(musl_version).tar.gz:
wget -c http://musl.libc.org/releases/$@
musl-fts: musl-fts-$(musl-fts_version).tar.gz
musl-fts-$(musl-fts_version).tar.gz:
wget -c $(github)/void-linux/musl-fts/archive/v$(musl-fts_version).tar.gz \
-O $@
ncurses: ncurses-${ncurses_version}.tar.gz
ncurses-${ncurses_version}.tar.gz:

8
include/mk/src-config.mk

@ -15,7 +15,7 @@ ifndef colormk
include hhl.colors.mk
endif
ifeq ($(filter armv7l aarch64, $(arch)), $(arch))
ifeq ($(filter armv6 armv7l aarch64, $(arch)), $(arch))
tgt = $(arch)-unknown-linux-gnueabi
else
tgt = $(arch)-unknown-linux-gnu
@ -26,6 +26,12 @@ ifeq ($(filter armv7l aarch64, $(bld_arch)), $(bld_arch))
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)
exec_prefix ?= ${DESTDIR}${install_prefix}
bindir ?= ${exec_prefix}/bin

8
include/mk/targets.mk

@ -72,6 +72,14 @@ $(objdir):
install -d $@
endif
ifeq ($(use_configure),1)
show-config_opts:
$(info $(grn)$(config_opts)$(reset))
else
show-config_opts:
$(info $(red)Package does not use configure$(reset))
endif
$(distlocal):
$(info $(grn)=== Fetching $(distfile) ===$(reset))
$(MAKE) -C $(distdir) $(distfile)

5
include/mk/versions.mk

@ -4,6 +4,7 @@
# package versions - hhl base
acl_version = 2.2.53
argp-standalone_version = 1.4.1
attr_version = 2.4.48
autoconf_version = 2.71
automake_version = 1.16.3
@ -55,7 +56,7 @@ libnl_version = 3.5.0
libressl_version = 3.0.2
libtool_version = 2.4.6
libz_version = 1.2.8.2015.12.26
linux_version = 5.11
linux_version = 5.11.5
linux_rpi_version = 5.4.45
m4_version = 1.4.18
make_version = 4.3
@ -64,6 +65,8 @@ mandoc_version = 1.14.5
meson_version = 0.56.2
mpc_version = 1.2.1
mpfr_version = 4.1.0
musl_version = 1.2.2
musl-fts_version = 1.2.7
ncurses_version = 6.2
netbsd-curses_version = 0.3.1
ninja_version = 1.10.2

3
toolchain/Makefile

@ -21,6 +21,7 @@ subdirs += binutils
subdirs += gcc-pass1
subdirs += linux-headers
subdirs += glibc
#subdirs += musl
subdirs += gcc-pass2
installdirs += $(tooldir) $(global_srcdir) $(global_objdir)
@ -60,7 +61,7 @@ removedoc:
rm -rf $(tooldir)/share/man
remove-la:
find $(tooldir)/lib $(tooldir)/libexec -name '*.la' -delete
find $(tooldir) -name '*.la' -delete
reduce-size: strip removedoc remove-la

3
toolchain/gcc-pass2/Makefile

@ -6,9 +6,12 @@ include toolchain.mk
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 += --disable-multilib
config_opts += --disable-bootstrap
# For musl
#config_opts += --disable-libsanitizer
ifneq ($(filter i686 x86_64, $(arch)), $(arch))
config_opts += --disable-libsanitizer
endif

13
toolchain/musl/Makefile

@ -0,0 +1,13 @@
# Makefile - hhl - /src/toolchain/musl
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
#
distname = musl
distext = gz
include world.mk
export CFLAGS = --sysroot=$(DESTDIR)
config_opts += --host=$(tgt)
config_opts += --bindir=/bin
include targets.mk

6
world/Makefile

@ -49,6 +49,8 @@ subdirs += expat
#subdirs += intltool
subdirs += kmod
subdirs += gettext
# for musl
subdirs += argp-standalone
subdirs += elfutils
subdirs += libffi
subdirs += libressl
@ -68,6 +70,10 @@ subdirs += mandoc
subdirs += texinfo
subdirs += procps-ng
subdirs += util-linux
# for musl
#subdirs += argp-standalone
# for musl
#subdirs += musl-fts
subdirs += e2fsprogs
subdirs += haveged
subdirs += eudev

9
world/argp-standalone/Makefile

@ -0,0 +1,9 @@
# Makefile - hhl - /src/world/argp-standalone
# Copyright 2020 Nathan Fisher <nfisher.sr@gmail.com>
#
libname = argp
doinstall = true
cflags += -O2
cflags += -Wall
cflags += --sysroot=$(DESTDIR)
include hhl.staticlib.mk

3
world/argp-standalone/src/acconfig.h

@ -0,0 +1,3 @@
/* Global variables needed by argp */
#undef HAVE_PROGRAM_INVOCATION_NAME
#undef HAVE_PROGRAM_INVOCATION_SHORT_NAME

25
world/argp-standalone/src/argp-ba.c

@ -0,0 +1,25 @@
/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
Copyright (C) 1996-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* If set by the user program, it should point to string that is the
bug-reporting address for the program. It will be printed by argp_help if
the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
messages), embedded in a sentence that says something like `Report bugs to
ADDR.'. */
const char *argp_program_bug_address;

31
world/argp-standalone/src/argp-eexst.c

@ -0,0 +1,31 @@
/* Default definition for ARGP_ERR_EXIT_STATUS
Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sysexits.h>
#include "argp.h"
/* The exit status that argp will use when exiting due to a parsing error.
If not defined or set by the user program, this defaults to EX_USAGE from
<sysexits.h>. */
error_t argp_err_exit_status = EX_USAGE;

433
world/argp-standalone/src/argp-fmtstream.c

@ -0,0 +1,433 @@
/* Word-wrapping and line-truncating streams
Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This package emulates glibc `line_wrap_stream' semantics for systems that
don't have that. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#include <argp-fmtstream.h>
#include "argp-namefrob.h"
#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
#ifndef isblank
#define isblank(ch) ((ch)==' ' || (ch)=='\t')
#endif
#if 0
# include <wchar.h>
# include <libio/libioP.h>
#endif
#define INIT_BUF_SIZE 200
#define PRINTF_SIZE_GUESS 150
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
written on it with LMARGIN spaces and limits them to RMARGIN columns
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
replacing the whitespace before them with a newline and WMARGIN spaces.
Otherwise, chars beyond RMARGIN are simply dropped until a newline.
Returns NULL if there was an error. */
argp_fmtstream_t
__argp_make_fmtstream (FILE *stream,
size_t lmargin, size_t rmargin, ssize_t wmargin)
{
argp_fmtstream_t fs;
fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
if (fs != NULL)
{
fs->stream = stream;
fs->lmargin = lmargin;
fs->rmargin = rmargin;
fs->wmargin = wmargin;
fs->point_col = 0;
fs->point_offs = 0;
fs->buf = (char *) malloc (INIT_BUF_SIZE);
if (! fs->buf)
{
free (fs);
fs = 0;
}
else
{
fs->p = fs->buf;
fs->end = fs->buf + INIT_BUF_SIZE;
}
}
return fs;
}
#if 0
/* Not exported. */
#ifdef weak_alias
weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
#endif
#endif
/* Flush FS to its stream, and free it (but don't close the stream). */
void
__argp_fmtstream_free (argp_fmtstream_t fs)
{
__argp_fmtstream_update (fs);
if (fs->p > fs->buf)
{
#if 0
__fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
#else
fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
#endif
}
free (fs->buf);
free (fs);
}
#if 0
/* Not exported. */
#ifdef weak_alias
weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
#endif
#endif
/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
void
__argp_fmtstream_update (argp_fmtstream_t fs)
{
char *buf, *nl;
size_t len;
/* Scan the buffer for newlines. */
buf = fs->buf + fs->point_offs;
while (buf < fs->p)
{
size_t r;
if (fs->point_col == 0 && fs->lmargin != 0)
{
/* We are starting a new line. Print spaces to the left margin. */
const size_t pad = fs->lmargin;
if (fs->p + pad < fs->end)
{
/* We can fit in them in the buffer by moving the
buffer text up and filling in the beginning. */
memmove (buf + pad, buf, fs->p - buf);
fs->p += pad; /* Compensate for bigger buffer. */
memset (buf, ' ', pad); /* Fill in the spaces. */
buf += pad; /* Don't bother searching them. */
}
else
{
/* No buffer space for spaces. Must flush. */
size_t i;
for (i = 0; i < pad; i++)
{
#if 0
if (_IO_fwide (fs->stream, 0) > 0)
putwc_unlocked (L' ', fs->stream);
else
#endif
putc_unlocked (' ', fs->stream);
}
}
fs->point_col = pad;
}
len = fs->p - buf;
nl = memchr (buf, '\n', len);
if (fs->point_col < 0)
fs->point_col = 0;
if (!nl)
{
/* The buffer ends in a partial line. */
if (fs->point_col + len < fs->rmargin)
{
/* The remaining buffer text is a partial line and fits
within the maximum line width. Advance point for the
characters to be written and stop scanning. */
fs->point_col += len;
break;
}
else
/* Set the end-of-line pointer for the code below to
the end of the buffer. */
nl = fs->p;
}
else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
{
/* The buffer contains a full line that fits within the maximum
line width. Reset point and scan the next line. */
fs->point_col = 0;
buf = nl + 1;
continue;
}
/* This line is too long. */
r = fs->rmargin - 1;
if (fs->wmargin < 0)
{
/* Truncate the line by overwriting the excess with the
newline and anything after it in the buffer. */
if (nl < fs->p)
{
memmove (buf + (r - fs->point_col), nl, fs->p - nl);
fs->p -= buf + (r - fs->point_col) - nl;
/* Reset point for the next line and start scanning it. */
fs->point_col = 0;
buf += r + 1; /* Skip full line plus \n. */
}
else
{
/* The buffer ends with a partial line that is beyond the
maximum line width. Advance point for the characters
written, and discard those past the max from the buffer. */
fs->point_col += len;
fs->p -= fs->point_col - r;
break;
}
}
else
{
/* Do word wrap. Go to the column just past the maximum line
width and scan back for the beginning of the word there.
Then insert a line break. */
char *p, *nextline;
int i;
p = buf + (r + 1 - fs->point_col);
while (p >= buf && !isblank (*p))
--p;
nextline = p + 1; /* This will begin the next line. */
if (nextline > buf)
{
/* Swallow separating blanks. */
if (p >= buf)
do
--p;
while (p >= buf && isblank (*p));
nl = p + 1; /* The newline will replace the first blank. */
}
else
{
/* A single word that is greater than the maximum line width.
Oh well. Put it on an overlong line by itself. */
p = buf + (r + 1 - fs->point_col);
/* Find the end of the long word. */
do
++p;
while (p < nl && !isblank (*p));
if (p == nl)
{
/* It already ends a line. No fussing required. */
fs->point_col = 0;
buf = nl + 1;
continue;
}
/* We will move the newline to replace the first blank. */
nl = p;
/* Swallow separating blanks. */
do
++p;
while (isblank (*p));
/* The next line will start here. */
nextline = p;
}
/* Note: There are a bunch of tests below for
NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
at the end of the buffer, and NEXTLINE is in fact empty (and so
we need not be careful to maintain its contents). */
if ((nextline == buf + len + 1
? fs->end - nl < fs->wmargin + 1
: nextline - (nl + 1) < fs->wmargin)
&& fs->p > nextline)
{
/* The margin needs more blanks than we removed. */
if (fs->end - fs->p > fs->wmargin + 1)
/* Make some space for them. */
{
size_t mv = fs->p - nextline;
memmove (nl + 1 + fs->wmargin, nextline, mv);
nextline = nl + 1 + fs->wmargin;
len = nextline + mv - buf;
*nl++ = '\n';
}
else
/* Output the first line so we can use the space. */
{
#if 0
__fxprintf (fs->stream, "%.*s\n",
(int) (nl - fs->buf), fs->buf);
#else
if (nl > fs->buf)
fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
putc_unlocked ('\n', fs->stream);
#endif
len += buf - fs->buf;
nl = buf = fs->buf;
}
}
else
/* We can fit the newline and blanks in before
the next word. */
*nl++ = '\n';
if (nextline - nl >= fs->wmargin
|| (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
/* Add blanks up to the wrap margin column. */
for (i = 0; i < fs->wmargin; ++i)
*nl++ = ' ';
else
for (i = 0; i < fs->wmargin; ++i)
#if 0
if (_IO_fwide (fs->stream, 0) > 0)
putwc_unlocked (L' ', fs->stream);
else
#endif
putc_unlocked (' ', fs->stream);
/* Copy the tail of the original buffer into the current buffer
position. */
if (nl < nextline)
memmove (nl, nextline, buf + len - nextline);
len -= nextline - buf;
/* Continue the scan on the remaining lines in the buffer. */
buf = nl;
/* Restore bufp to include all the remaining text. */
fs->p = nl + len;
/* Reset the counter of what has been output this line. If wmargin
is 0, we want to avoid the lmargin getting added, so we set
point_col to a magic value of -1 in that case. */
fs->point_col = fs->wmargin ? fs->wmargin : -1;
}
}
/* Remember that we've scanned as far as the end of the buffer. */
fs->point_offs = fs->p - fs->buf;
}
/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
growing the buffer, or by flushing it. True is returned iff we succeed. */
int
__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
{
if ((size_t) (fs->end - fs->p) < amount)
{
ssize_t wrote;
/* Flush FS's buffer. */
__argp_fmtstream_update (fs);
#if 0
__fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
wrote = fs->p - fs->buf;
#else
wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
#endif
if (wrote == fs->p - fs->buf)
{
fs->p = fs->buf;
fs->point_offs = 0;
}
else
{
fs->p -= wrote;
fs->point_offs -= wrote;
memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
return 0;
}
if ((size_t) (fs->end - fs->buf) < amount)
/* Gotta grow the buffer. */
{
size_t old_size = fs->end - fs->buf;
size_t new_size = old_size + amount;
char *new_buf;
if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
{
__set_errno (ENOMEM);
return 0;
}
fs->buf = new_buf;
fs->end = new_buf + new_size;
fs->p = fs->buf;
}
}
return 1;
}
ssize_t
__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
{
int out;
size_t avail;
size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
do
{
va_list args;
if (! __argp_fmtstream_ensure (fs, size_guess))
return -1;
va_start (args, fmt);
avail = fs->end - fs->p;
out = vsnprintf (fs->p, avail, fmt, args);
va_end (args);
if ((size_t) out >= avail)
size_guess = out + 1;
}
while ((size_t) out >= avail);
fs->p += out;
return out;
}
#if 0
/* Not exported. */
#ifdef weak_alias
weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
#endif
#endif
#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */

263
world/argp-standalone/src/argp-fmtstream.h

@ -0,0 +1,263 @@
/* Word-wrapping and line-truncating streams.
Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* This package emulates glibc `line_wrap_stream' semantics for systems that
don't have that. If the system does have it, it is just a wrapper for
that. This header file is only used internally while compiling argp, and
shouldn't be installed. */
#ifndef _ARGP_FMTSTREAM_H
#define _ARGP_FMTSTREAM_H
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#ifndef PRINTF_STYLE
# if __GNUC__ >= 2
# define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a)))
# else
# define PRINTF_STYLE(f, a)
# endif
#endif
#if 0
/* line_wrap_stream is available, so use that. */
#define ARGP_FMTSTREAM_USE_LINEWRAP
#endif
#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
/* Just be a simple wrapper for line_wrap_stream; the semantics are
*slightly* different, as line_wrap_stream doesn't actually make a new
object, it just modifies the given stream (reversibly) to do
line-wrapping. Since we control who uses this code, it doesn't matter. */
#include <linewrap.h>
typedef FILE *argp_fmtstream_t;
#define argp_make_fmtstream line_wrap_stream
#define __argp_make_fmtstream line_wrap_stream
#define argp_fmtstream_free line_unwrap_stream
#define __argp_fmtstream_free line_unwrap_stream
#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
#define argp_fmtstream_puts(fs,str) fputs(str,fs)
#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
#define __argp_fmtstream_printf fprintf
#define argp_fmtstream_printf fprintf
#define __argp_fmtstream_lmargin line_wrap_lmargin
#define argp_fmtstream_lmargin line_wrap_lmargin
#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
#define __argp_fmtstream_rmargin line_wrap_rmargin
#define argp_fmtstream_rmargin line_wrap_rmargin
#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
#define __argp_fmtstream_wmargin line_wrap_wmargin
#define argp_fmtstream_wmargin line_wrap_wmargin
#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
#define __argp_fmtstream_point line_wrap_point
#define argp_fmtstream_point line_wrap_point
#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
/* Guess we have to define our own version. */
struct argp_fmtstream
{
FILE *stream; /* The stream we're outputting to. */
size_t lmargin, rmargin; /* Left and right margins. */
ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
/* Point in buffer to which we've processed for wrapping, but not output. */
size_t point_offs;
/* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
ssize_t point_col;
char *buf; /* Output buffer. */
char *p; /* Current end of text in BUF. */
char *end; /* Absolute end of BUF. */
};
typedef struct argp_fmtstream *argp_fmtstream_t;
/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
written on it with LMARGIN spaces and limits them to RMARGIN columns
total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
replacing the whitespace before them with a newline and WMARGIN spaces.
Otherwise, chars beyond RMARGIN are simply dropped until a newline.
Returns NULL if there was an error. */
extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
size_t __lmargin,
size_t __rmargin,
ssize_t __wmargin);
extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
size_t __lmargin,
size_t __rmargin,
ssize_t __wmargin);
/* Flush __FS to its stream, and free it (but don't close the stream). */
extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
extern void argp_fmtstream_free (argp_fmtstream_t __fs);
extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
const char *__fmt, ...)
PRINTF_STYLE(2,3);
extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
const char *__fmt, ...)
PRINTF_STYLE(2,3);
/* Access macros for various bits of state. */
#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
/* Internal routines. */
extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
#if 1
/* Inline versions of above routines. */
#if 1
#define __argp_fmtstream_putc argp_fmtstream_putc
#define __argp_fmtstream_puts argp_fmtstream_puts
#define __argp_fmtstream_write argp_fmtstream_write
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
#define __argp_fmtstream_point argp_fmtstream_point
#define __argp_fmtstream_update _argp_fmtstream_update
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
#endif
#ifndef ARGP_FS_EI
#define ARGP_FS_EI static inline
#endif
ARGP_FS_EI size_t
__argp_fmtstream_write (argp_fmtstream_t __fs, const char *__str, size_t __len)
{
if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
{
memcpy (__fs->p, __str, __len);
__fs->p += __len;
return __len;
}
else
return 0;
}
ARGP_FS_EI int
__argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str)
{
size_t __len = strlen (__str);
if (__len)
{
size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
return __wrote == __len ? 0 : -1;
}
else
return 0;
}
ARGP_FS_EI int
__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
{
if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
return *__fs->p++ = __ch;
else
return EOF;
}
/* Set __FS's left margin to __LMARGIN and return the old value. */
ARGP_FS_EI size_t
__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
{
size_t __old;
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
__old = __fs->lmargin;
__fs->lmargin = __lmargin;
return __old;
}
/* Set __FS's right margin to __RMARGIN and return the old value. */
ARGP_FS_EI size_t
__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
{
size_t __old;
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
__old = __fs->rmargin;
__fs->rmargin = __rmargin;
return __old;
}
/* Set FS's wrap margin to __WMARGIN and return the old value. */
ARGP_FS_EI size_t
__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
{
size_t __old;
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
__old = __fs->wmargin;
__fs->wmargin = __wmargin;
return __old;
}
/* Return the column number of the current output point in __FS. */
ARGP_FS_EI size_t
__argp_fmtstream_point (argp_fmtstream_t __fs)
{
if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
__argp_fmtstream_update (__fs);
return __fs->point_col >= 0 ? __fs->point_col : 0;
}
#if 1
#undef __argp_fmtstream_putc
#undef __argp_fmtstream_puts
#undef __argp_fmtstream_write
#undef __argp_fmtstream_set_lmargin
#undef __argp_fmtstream_set_rmargin
#undef __argp_fmtstream_set_wmargin
#undef __argp_fmtstream_point
#undef __argp_fmtstream_update
#undef __argp_fmtstream_ensure
#endif
#endif /* __OPTIMIZE__ */
#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
#endif /* argp-fmtstream.h */

1890
world/argp-standalone/src/argp-help.c
File diff suppressed because it is too large
View File

149
world/argp-standalone/src/argp-namefrob.h

@ -0,0 +1,149 @@
/* Name frobnication for compiling argp outside of glibc
Copyright (C) 1997-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#if 1
/* This code is written for inclusion in gnu-libc, and uses names in the
namespace reserved for libc. If we're not compiling in libc, define those
names to be the normal ones instead. */
/* argp-parse functions */
#undef __argp_parse
#define __argp_parse argp_parse
#undef __option_is_end
#define __option_is_end _option_is_end
#undef __option_is_short
#define __option_is_short _option_is_short
#undef __argp_input
#define __argp_input _argp_input
/* argp-help functions */
#undef __argp_help
#define __argp_help argp_help
#undef __argp_error
#define __argp_error argp_error
#undef __argp_failure
#define __argp_failure argp_failure
#undef __argp_state_help
#define __argp_state_help argp_state_help
#undef __argp_usage
#define __argp_usage argp_usage
/* argp-fmtstream functions */
#undef __argp_make_fmtstream
#define __argp_make_fmtstream argp_make_fmtstream
#undef __argp_fmtstream_free
#define __argp_fmtstream_free argp_fmtstream_free
#undef __argp_fmtstream_putc
#define __argp_fmtstream_putc argp_fmtstream_putc
#undef __argp_fmtstream_puts
#define __argp_fmtstream_puts argp_fmtstream_puts
#undef __argp_fmtstream_write
#define __argp_fmtstream_write argp_fmtstream_write
#undef __argp_fmtstream_printf
#define __argp_fmtstream_printf argp_fmtstream_printf
#undef __argp_fmtstream_set_lmargin
#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
#undef __argp_fmtstream_set_rmargin
#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
#undef __argp_fmtstream_set_wmargin
#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
#undef __argp_fmtstream_point
#define __argp_fmtstream_point argp_fmtstream_point
#undef __argp_fmtstream_update
#define __argp_fmtstream_update _argp_fmtstream_update
#undef __argp_fmtstream_ensure
#define __argp_fmtstream_ensure _argp_fmtstream_ensure
#undef __argp_fmtstream_lmargin
#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
#undef __argp_fmtstream_rmargin
#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
#undef __argp_fmtstream_wmargin
#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
/* normal libc functions we call */
#undef __flockfile
#define __flockfile flockfile
#undef __funlockfile
#define __funlockfile funlockfile
#undef __mempcpy
#define __mempcpy mempcpy
#undef __sleep
#define __sleep sleep
#undef __strcasecmp
#define __strcasecmp strcasecmp
#undef __strchrnul
#define __strchrnul strchrnul
#undef __strerror_r
#define __strerror_r strerror_r
#undef __strndup
#define __strndup strndup
#if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED
# define clearerr_unlocked(x) clearerr (x)
#endif
#if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED
# define feof_unlocked(x) feof (x)
# endif
#if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED
# define ferror_unlocked(x) ferror (x)
# endif
#if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED
# define fflush_unlocked(x) fflush (x)
# endif
#if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED
# define fgets_unlocked(x,y,z) fgets (x,y,z)
# endif
#if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED
# define fputc_unlocked(x,y) fputc (x,y)
# endif
#if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
# define fputs_unlocked(x,y) fputs (x,y)
# endif
#if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
# endif
#if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
# endif
#if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED
# define getc_unlocked(x) getc (x)
# endif
#if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED
# define getchar_unlocked() getchar ()
# endif
#if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED
# define putc_unlocked(x,y) putc (x,y)
# endif
#if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED
# define putchar_unlocked(x) putchar (x)
# endif
extern char *__argp_basename (char *name);
#endif /* !_LIBC */
#ifndef __set_errno
#define __set_errno(e) (errno = (e))
#endif
#if 0 || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
# define __argp_short_program_name() (program_invocation_short_name)
#else
extern char *__argp_short_program_name (void);
#endif

941
world/argp-standalone/src/argp-parse.c

@ -0,0 +1,941 @@
/* Hierarchial argument parsing, layered over getopt
Copyright (C) 1995-2021 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# if HAVE_ALLOCA_H || 0
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <getopt.h>
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
# if defined HAVE_LIBINTL_H || 0
# include <libintl.h>
# if 0
# undef dgettext
# define dgettext(domain, msgid) \
__dcgettext (domain, msgid, LC_MESSAGES)
# endif
# else
# define dgettext(domain, msgid) (msgid)
# define gettext(msgid) (msgid)
# endif
#endif
#ifndef N_
# define N_(msgid) (msgid)
#endif
#include <argp.h>
#include "argp-namefrob.h"
/* Getopt return values. */
#define KEY_END (-1) /* The end of the options. */
#define KEY_ARG 1 /* A non-option argument. */
#define KEY_ERR '?' /* An error parsing the options. */
/* The meta-argument used to prevent any further arguments being interpreted
as options. */
#define QUOTE "--"
/* The number of bits we steal in a long-option value for our own use. */
#define GROUP_BITS CHAR_BIT
/* The number of bits available for the user value. */
#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
#define USER_MASK ((1 << USER_BITS) - 1)
/* EZ alias for ARGP_ERR_UNKNOWN. */
#define EBADKEY ARGP_ERR_UNKNOWN
/* Default options. */
/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
you can force the program to continue by attaching a debugger and setting
it to 0 yourself. */
static volatile int _argp_hang;
#define OPT_PROGNAME -2
#define OPT_USAGE -3
#define OPT_HANG -4
static const struct argp_option argp_default_options[] =
{
{"help", '?', 0, 0, N_("Give this help list"), -1},
{"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")},
{"program-name",OPT_PROGNAME, N_("NAME"), OPTION_HIDDEN,
N_("Set the program name")},
{"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
N_("Hang for SECS seconds (default 3600)")},
{0, 0}
};
static error_t
argp_default_parser (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case '?':
__argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
break;
case OPT_USAGE:
__argp_state_help (state, state->out_stream,
ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
break;
case OPT_PROGNAME: /* Set the program name. */
#if 0 || HAVE_DECL_PROGRAM_INVOCATION_NAME
program_invocation_name = arg;
#endif
/* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
__PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
to be that, so we have to be a bit careful here.] */
/* Update what we use for messages. */
state->name = strrchr (arg, '/');
if (state->name)
state->name++;
else
state->name = arg;
#if 0 || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
program_invocation_short_name = state->name;
#endif
if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
== ARGP_PARSE_ARGV0)
/* Update what getopt uses too. */
state->argv[0] = arg;
break;
case OPT_HANG:
_argp_hang = atoi (arg ? arg : "3600");
while (_argp_hang-- > 0)
__sleep (1);
break;
default:
return EBADKEY;
}
return 0;
}
static const struct argp argp_default_argp =
{argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
static const struct argp_option argp_version_options[] =
{
{"version", 'V', 0, 0, N_("Print program version"), -1},
{0, 0}
};
static error_t
argp_version_parser (int key, char *arg, struct argp_state *state)
{
switch (key)
{
case 'V':
if (argp_program_version_hook)
(*argp_program_version_hook) (state->out_stream, state);
else if (argp_program_version)
fprintf (state->out_stream, "%s\n", argp_program_version);
else
__argp_error (state, dgettext (state->root_argp->argp_domain,
"(PROGRAM ERROR) No version known!?"));
if (! (state->flags & ARGP_NO_EXIT))
exit (0);
break;
default:
return EBADKEY;
}
return 0;
}
static const struct argp argp_version_argp =
{argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
/* Returns the offset into the getopt long options array LONG_OPTIONS of a
long option with called NAME, or -1 if none is found. Passing NULL as
NAME will return the number of options. */
static int
find_long_option (struct option *long_options, const char *name)
{
struct option *l = long_options;
while (l->name != NULL)
if (name != NULL && strcmp (l->name, name) == 0)
return l - long_options;
else
l++;
if (name == NULL)
return l - long_options;
else
return -1;
}
/* The state of a `group' during parsing. Each group corresponds to a
particular argp structure from the tree of such descending from the top
level argp passed to argp_parse. */
struct group
{
/* This group's parsing function. */
argp_parser_t parser;
/* Which argp this group is from. */
const struct argp *argp;
/* Points to the point in SHORT_OPTS corresponding to the end of the short
options for this group. We use it to determine from which group a
particular short options is from. */
char *short_end;
/* The number of non-option args sucessfully handled by this parser. */
unsigned args_processed;
/* This group's parser's parent's group. */
struct group *parent;
unsigned parent_index; /* And the our position in the parent. */
/* These fields are swapped into and out of the state structure when
calling this group's parser. */
void *input, **child_inputs;
void *hook;
};
/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
from STATE before calling, and back into state afterwards. If GROUP has
no parser, EBADKEY is returned. */
static error_t
group_parse (struct group *group, struct argp_state *state, int key, char *arg)
{
if (group->parser)
{
error_t err;
state->hook = group->hook;
state->input = group->input;
state->child_inputs = group->child_inputs;
state->arg_num = group->args_processed;
err = (*group->parser)(key, arg, state);
group->hook = state->hook;
return err;
}
else
return EBADKEY;
}
struct parser
{
const struct argp *argp;
/* SHORT_OPTS is the getopt short options string for the union of all the
groups of options. */
char *short_opts;
/* LONG_OPTS is the array of getop long option structures for the union of
all the groups of options. */
struct option *long_opts;
/* States of the various parsing groups. */
struct group *groups;
/* The end of the GROUPS array. */
struct group *egroup;
/* An vector containing storage for the CHILD_INPUTS field in all groups. */
void **child_inputs;
/* True if we think using getopt is still useful; if false, then
remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is
cleared whenever getopt returns KEY_END, but may be set again if the user
moves the next argument pointer backwards. */
int try_getopt;
/* State block supplied to parsing routines. */
struct argp_state state;
/* Memory used by this parser. */
void *storage;
};
/* The next usable entries in the various parser tables being filled in by
convert_options. */
struct parser_convert_state
{
struct parser *parser;
char *short_end;
struct option *long_end;
void **child_inputs_end;
};
/* Converts all options in ARGP (which is put in GROUP) and ancestors
into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
CVT->LONG_END are the points at which new options are added. Returns the
next unused group entry. CVT holds state used during the conversion. */
static struct group *
convert_options (const struct argp *argp,
struct group *parent, unsigned parent_index,
struct group *group, struct parser_convert_state *cvt)
{
/* REAL is the most recent non-alias value of OPT. */
const struct argp_option *real = argp->options;
const struct argp_child *children = argp->children;
if (real || argp->parser)
{
const struct argp_option *opt;
if (real)
for (opt = real; !__option_is_end (opt); opt++)
{
if (! (opt->flags & OPTION_ALIAS))
/* OPT isn't an alias, so we can use values from it. */
real = opt;
if (! (real->flags & OPTION_DOC))
/* A real option (not just documentation). */
{
if (__option_is_short (opt))
/* OPT can be used as a short option. */
{
*cvt->short_end++ = opt->key;
if (real->arg)
{
*cvt->short_end++ = ':';
if (real->flags & OPTION_ARG_OPTIONAL)
*cvt->short_end++ = ':';
}
*cvt->short_end = '\0'; /* keep 0 terminated */
}
if (opt->name
&& find_long_option (cvt->parser->long_opts, opt->name) < 0)
/* OPT can be used as a long option. */