Browse Source
Testing musl support, disabled by default
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 elsewhereodin
280 changed files with 23725 additions and 127 deletions
-
12Makefile
-
19distfiles/Makefile
-
8include/mk/src-config.mk
-
8include/mk/targets.mk
-
5include/mk/versions.mk
-
3toolchain/Makefile
-
3toolchain/gcc-pass2/Makefile
-
13toolchain/musl/Makefile
-
6world/Makefile
-
9world/argp-standalone/Makefile
-
3world/argp-standalone/src/acconfig.h
-
25world/argp-standalone/src/argp-ba.c
-
31world/argp-standalone/src/argp-eexst.c
-
433world/argp-standalone/src/argp-fmtstream.c
-
263world/argp-standalone/src/argp-fmtstream.h
-
1890world/argp-standalone/src/argp-help.c
-
149world/argp-standalone/src/argp-namefrob.h
-
941world/argp-standalone/src/argp-parse.c
-
24world/argp-standalone/src/argp-pv.c
-
31world/argp-standalone/src/argp-pvh.c
-
212world/argp-standalone/src/argp-test.c
-
582world/argp-standalone/src/argp.h
-
18world/argp-standalone/src/mempcpy.c
-
21world/argp-standalone/src/strchrnul.c
-
31world/argp-standalone/src/strndup.c
-
1world/bin/blkdiscard/LICENSE
-
6world/bin/blkdiscard/Makefile
-
12world/bin/blkdiscard/man/blkdiscard.8
-
48world/bin/blkdiscard/src/blkdiscard.c
-
1world/bin/chgrp/LICENSE
-
6world/bin/chgrp/Makefile
-
75world/bin/chgrp/src/chgrp.c
-
1world/bin/chvt/LICENSE
-
6world/bin/chvt/Makefile
-
15world/bin/chvt/man/chvt.1
-
67world/bin/chvt/src/chvt.c
-
1world/bin/clear/LICENSE
-
6world/bin/clear/Makefile
-
11world/bin/clear/man/clear.1
-
23world/bin/clear/src/clear.c
-
1world/bin/cols/LICENSE
-
6world/bin/cols/Makefile
-
56world/bin/cols/man/cols.1
-
98world/bin/cols/src/cols.c
-
1world/bin/cron/LICENSE
-
6world/bin/cron/Makefile
-
23world/bin/cron/man/cron.1
-
566world/bin/cron/src/cron.c
-
1world/bin/ctrlaltdel/LICENSE
-
6world/bin/ctrlaltdel/Makefile
-
31world/bin/ctrlaltdel/man/ctrlaltdel.8
-
42world/bin/ctrlaltdel/src/ctrlaltdel.c
-
1world/bin/fallocate/LICENSE
-
6world/bin/fallocate/Makefile
-
33world/bin/fallocate/man/fallocate.1
-
55world/bin/fallocate/src/fallocate.c
-
1world/bin/freeramdisk/LICENSE
-
6world/bin/freeramdisk/Makefile
-
13world/bin/freeramdisk/man/freeramdisk.8
-
39world/bin/freeramdisk/src/freeramdisk.c
-
1world/bin/fsfreeze/LICENSE
-
6world/bin/fsfreeze/Makefile
-
33world/bin/fsfreeze/man/fsfreeze.8
-
54world/bin/fsfreeze/src/fsfreeze.c
-
1world/bin/getty/LICENSE
-
6world/bin/getty/Makefile
-
22world/bin/getty/man/getty.8
-
140world/bin/getty/src/getty.c
-
1world/bin/halt/LICENSE
-
6world/bin/halt/Makefile
-
21world/bin/halt/man/halt.8
-
51world/bin/halt/src/halt.c
-
1world/bin/hwclock/LICENSE
-
6world/bin/hwclock/Makefile
-
31world/bin/hwclock/man/hwclock.8
-
159world/bin/hwclock/src/hwclock.c
-
1world/bin/insmod/LICENSE
-
6world/bin/insmod/Makefile
-
18world/bin/insmod/man/insmod.8
-
69world/bin/insmod/src/insmod.c
-
1world/bin/kill/LICENSE
-
6world/bin/kill/Makefile
-
47world/bin/kill/man/kill.1
-
130world/bin/kill/src/kill.c
-
1world/bin/killall5/LICENSE
-
6world/bin/killall5/Makefile
-
31world/bin/killall5/man/killall5.8
-
111world/bin/killall5/src/killall5.c
-
1world/bin/lastlog/LICENSE
-
6world/bin/lastlog/Makefile
-
18world/bin/lastlog/man/lastlog.8
-
78world/bin/lastlog/src/lastlog.c
-
1world/bin/lsmod/LICENSE
-
6world/bin/lsmod/Makefile
-
13world/bin/lsmod/man/lsmod.8
-
67world/bin/lsmod/src/lsmod.c
-
1world/bin/lsusb/LICENSE
-
6world/bin/lsusb/Makefile
-
13world/bin/lsusb/man/lsusb.8
-
58world/bin/lsusb/src/lsusb.c
@ -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 |
|||
|
@ -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 |
@ -0,0 +1,3 @@ |
|||
/* Global variables needed by argp */ |
|||
#undef HAVE_PROGRAM_INVOCATION_NAME |
|||
#undef HAVE_PROGRAM_INVOCATION_SHORT_NAME |
@ -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; |
@ -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; |
@ -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 */ |
@ -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
File diff suppressed because it is too large
View File
@ -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 |
@ -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. */ |
|||