├── .gitignore ├── ChangeLog ├── Makefile.am ├── README.md ├── Versions ├── acconfig.h ├── acinclude.m4 ├── argp-ba.c ├── argp-eexst.c ├── argp-fmtstream.c ├── argp-fmtstream.h ├── argp-help.c ├── argp-namefrob.h ├── argp-parse.c ├── argp-pv.c ├── argp-pvh.c ├── argp-test.c ├── argp.h ├── configure.ac ├── mempcpy.c ├── stamp-h.in ├── strchrnul.c ├── strndup.c └── testsuite ├── Makefile.am ├── ex1-test ├── ex1.c ├── ex3.c ├── ex4.c ├── permute-test └── run-tests /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | 4 | autom4te.cache/ 5 | .deps/ 6 | 7 | aclocal.m4 8 | stamp-h1 9 | config.* 10 | compile 11 | configure 12 | depcomp 13 | install-sh 14 | missing 15 | Makefile.in 16 | 17 | Makefile 18 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2021-02-16 Érico Nogueira 2 | 3 | * configure.ac: Check for header. 4 | * argp-help.c: Add dgettext_safe wrapper. 5 | * configure.ac: Bumped version to 1.4.1. 6 | 7 | 2021-02-10 Érico Nogueira 8 | 9 | * configure.ac: Bumped version to 1.4.0. 10 | 11 | 2021-02-10 Érico Nogueira 12 | 13 | * Updated argp to glibc 2.33. 14 | * README.md: create file. 15 | 16 | 2004-02-23 Niels Möller 17 | 18 | * configure.ac: Bumped version to standalone-1.3. 19 | 20 | Portability to Mac OS X (fixes by Akim Demaille) 21 | 22 | * argp/Makefile.am (libargp_a_SOURCES): Remove the duplicate 23 | inclusion of argp-eexst.c. 24 | * argp/argp-ba.c, argp/argp-pv.c, argp/argp-pvh.c: Initialize the 25 | variables, otherwise on Darwin linking fails if the user does not 26 | define these variables. 27 | 28 | 2003-04-28 Niels Möller 29 | 30 | * argp-parse.c: Use standard alloca blurb from the autoconf 31 | manual. 32 | * argp-help.c: Updated alloca blurb to use the same as 33 | argp-parse.c. 34 | 35 | 2003-04-24 Niels Möller 36 | 37 | * argp.h: Added workaround for __restrict. 38 | 39 | 2003-03-13 Niels Möller 40 | 41 | * Released argp-standalone-1.2. 42 | 43 | * Updated copyright years. 44 | 45 | 2003-03-03 Niels Möller 46 | 47 | * argp-fmtstream.h: Don't include config.h here, let the .c-files 48 | do that. Deleted definition of PRINTF_STYLE, that's in config.h. 49 | When defining or disabling i/o locking functions, use uppercase 50 | macro names like PUTC_UNLOCKED. This avoids conflicts if the 51 | underlying functions are really macros defined by stdio. For 52 | example on freebsd. Updated the files using these functions. 53 | 54 | 2003-03-02 Niels Möller 55 | 56 | * argp-help.c: Don't include malloc.h. If any system still needs 57 | it, we need a configure test for it. 58 | (hol_entry_help): Don't use a non-constant initializer, as that's 59 | a GNU C extension. 60 | 61 | 2003-02-23 Niels Moller 62 | 63 | * configure.ac: Use LSH_GCC_ATTRIBUTES. Deleted the definition of 64 | UNUSED from the files that used it, it's now in config.h. 65 | 66 | 2003-02-16 Niels Möller 67 | 68 | * argp-fmtstream.h: When disabling fwrite_unlocked, #undef it first. 69 | 70 | * testsuite/permute-test: diff -q is not portable. 71 | Redirect to /dev/null instead. 72 | 73 | 2003-02-12 Niels Möller 74 | 75 | * argp-fmtstream.h: When disabling putc_unlocked, #undef it first. 76 | 77 | 2003-02-10 Niels Möller 78 | 79 | * configure.ac (ARGP_CHECK_FUNC): Use AS_VAR_GET. Use AH_TEMPLATE. 80 | 81 | 2003-02-10 Niels Möller 82 | 83 | * configure.ac (ARGP_CHECK_FUNC): New macro. Use it to test for 84 | putc_unlocked. 85 | 86 | 2003-02-05 Niels Möller 87 | 88 | * argp-parse.c (argp_default_options): Fixed initializer. 89 | * argp-test.c (options): Likewise. 90 | 91 | * testsuite/permute-test (die): Fixed sh-compatible function 92 | definition. 93 | 94 | * testsuite/ex4.c: Don't use error.h and the error function. 95 | 96 | * .bootstrap: New file. 97 | 98 | 2003-02-05 Niels Möller 99 | 100 | * Makefile.am (all): Deleted the explicit all target. 101 | (LIBOBJS): Added explicit substitution. 102 | 103 | * testsuite/ex3.c, testsuite/ex4.c: Complete initializers, to 104 | avoid warnings from gcc. 105 | 106 | * configure.ac: Updated for current autoconf and automake. 107 | Fixed AC_CONFIG_HEADER call. 108 | Use AC_GNU_SOURCE. 109 | Use AC_CHECK_DECLS to check for program_invocation_name and 110 | program_invocation_short_name. 111 | 112 | * argp-test.c (sub_options): Complete initializer, to avoid 113 | warnings from gcc. 114 | (sub_argp): Likewise. 115 | (options): Likewise. 116 | 117 | * argp-parse.c (argp_default_parser): 118 | HAVE_PROGRAM_INVOCATION_SHORT_NAME renamed to 119 | HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME. 120 | (argp_default_options): Complete initializer, to avoid 121 | warnings from gcc. 122 | 123 | * argp-help.c (uparam_names): Complete initializer, to avoid 124 | warnings from gcc. 125 | (__argp_short_program_name): HAVE_PROGRAM_INVOCATION_NAME renamed 126 | to HAVE_DECL_PROGRAM_INVOCATION_NAME. Similarly for 127 | HAVE_PROGRAM_INVOCATION_SHORT_NAME. 128 | 129 | * acinclude.m4: Deleted file. 130 | 131 | 2003-02-04 Niels Möller 132 | 133 | * configure.ac: Bumped version to standalone-1.2. 134 | 135 | * argp-parse.c (parser_parse_next): Call exchange before 136 | processing the final arguments. Fixes bug reported by Akim Demaille. 137 | 138 | * Makefile.am (SUBDIRS): Added testsuite. 139 | 140 | * configure.ac: Output testsuite/Makefile. 141 | 142 | * testsuite/run-tests: Script copied from nettle. 143 | 144 | * testsuite/permute-test: New testcase, exercising 145 | argument option permuting. 146 | 147 | * testsuite/ex1-test: New testcase. 148 | 149 | * testsuite/ex1.c, testsuite/ex3.c, 150 | testsuite/ex4.c: Added glibc example programs. 151 | 152 | 2002-07-18 Niels Möller 153 | 154 | * configure.ac: Don't use -ggdb3 with gcc-2.96. 155 | 156 | 2002-05-06 Niels Möller 157 | 158 | * configure.ac: Use AH_TEMPLATE for 159 | PROGRAM_INVOCATION_NAME and PROGRAM_INVOCATION_SHORT_NAME. The 160 | third arg to AC_DEFINE_UNQUOTED seems not to work here. 161 | 162 | 2002-05-05 Niels Möller 163 | 164 | * acconfig.h: Deleted file. 165 | 166 | * configure.ac: Pass no arguments to AM_INIT_AUTOMAKE. 167 | Don't substitute LIBOBJS. 168 | 169 | * acinclude.m4: Use the three-argument form of 170 | AC_DEFINE_UNQUOTED. 171 | 172 | * configure.ac: Update for automake-1.6. 173 | * configure.ac: Renamed file, used to be configure.in. 174 | 175 | 2001-03-26 Niels Möller 176 | 177 | * configure.in: Bumped argp version to standalone-1.1. 178 | 179 | 2001-03-26 Niels Möller 180 | 181 | * configure.in (CPPFLAGS): Added -D_GNU_SOURCE. 182 | 183 | 2001-02-18 Niels Möller 184 | 185 | * argp-parse.c (argp_default_parser): Let OPT_HANG print 186 | the process id to stderr. 187 | 188 | 2001-01-15 Niels Möller 189 | 190 | * argp.h: #define PRINTF_STYLE, and use it instead of 191 | using __attribute__ directly. 192 | 193 | 2001-01-07 Niels Möller 194 | 195 | * argp.h: Added _argp_short_program_name and 196 | __argp_short_program_name. 197 | 198 | * argp-parse.c (parser_init): Use 199 | argp_short_program_name. 200 | (parser_parse_next): Removed old permutation handling code. 201 | 202 | 2001-01-06 Niels Möller 203 | 204 | * argp-namefrob.h: Added _argp_short_program_name. 205 | 206 | 2001-01-02 Niels Möller 207 | 208 | * argp-help.c (hol_entry_help): Avoid using a 209 | non-constant struct initializer. 210 | (UNUSED): Define as a macro expanding to __attribute__ ..., if 211 | compiling with gcc. 212 | 213 | * argp-fmtstream.h (PRINTF_STYLE): Define this macro, 214 | to expand to __attribute__ ... if compiling with gcc. 215 | 216 | * argp-fmtstream.c (__argp_fmtstream_write, 217 | __argp_fmtstream_puts, __argp_fmtstream_putc): Duplicate the 218 | inline definitions in argp-fmtstream.h, for compilers that don't 219 | do inlining. 220 | 221 | 2000-12-28 Niels Möller 222 | 223 | * argp-help.c (fill_in_uparams): Use unsigned char * for 224 | VAR and ARG. Fixed calls of isalnum, isspace and friends, reported 225 | by Kalle Olavi Niemitalo. 226 | (canon_doc_option): Fixed calls of isalnum, isspace and friends, 227 | reported by Kalle Olavi Niemitalo. 228 | (hol_entry_cmp): Fixed calls of tolower, reported by Kalle Olavi 229 | Niemitalo. 230 | 231 | 2000-12-23 Niels Möller 232 | 233 | * acinclude.m4: New file. 234 | * acinclude.m4: Reverted the definition of AC_CHECK_VAR 235 | to take includes as argument, and renamed it to ARGP_CHECK_VAR. 236 | 237 | 2000-12-11 Niels Möller 238 | 239 | * Removed getopt.c, getopt.h and getopt1.c from the src/argp 240 | directory. 241 | 242 | * argp-parse.c (match_option, ARGP_COMPLETE): #if:ed out 243 | completion code for long options. 244 | 245 | 2000-11-30 Niels Möller 246 | 247 | * argp-parse.c (match_option): Better abbreviations. 248 | Replaced try_getopt with args_only, changed calling convention for 249 | parser_parse_arg. 250 | 251 | * configure.in: Don't check for getopt. 252 | 253 | * argp.h: Don't include getopt.h. 254 | 255 | * argp-parse.c (calc_sizes): Updated comment. 256 | 257 | 2000-11-29 Niels Möller 258 | 259 | * configure.in: Use AC_REPLACE_FUNCS for mempcpy, strndup 260 | and strchrnul. 261 | (AC_CHECK_VAR): Changed second argument to take the type of the 262 | variable. 263 | 264 | * argp-parse.c (struct parser): New fields 265 | posixly_correct and ordering. 266 | (parser_init): Choose ordering. 267 | (enum arg_type): New value ARG_LONG_ONLY. 268 | (parser_parse_next): Added error messages similar to getopt's. 269 | 270 | * argp-help.c (STRNDUP): New macro to refer to strndup 271 | or __strndup, as appropriate. 272 | (STRERROR): Define this macro as a wrapper for strerror or 273 | sys_errlist. 274 | (__argp_basename): New function. 275 | 276 | * argp-namefrob.h (__argp_basename): Added 277 | __argp_basename. 278 | 279 | * Makefile.am (libargp_a_LIBADD): Include LIBOBJS in 280 | libargp.a. 281 | 282 | * argp.h: Added prototype for _argp_basename and 283 | __argp_basename. 284 | 285 | * strndup.c, strchrnul.c mempcpy.c: 286 | Moved replacement functions to separate files. 287 | 288 | 2000-11-28 Niels Möller 289 | 290 | * argp-parse.c: Deleted getopt-related code. 291 | (struct parser): New field nextchar. Deleted fields try_getotp and long_opts. 292 | (find_short_option): New function. 293 | (match_option): New function. 294 | (find_long_option): New function. 295 | (struct parser_convert_state): Deleted field long_end. 296 | (convert_options): Don't build getopt_long-style option array. 297 | (parser_convert): Deleted FLAGS arument. 298 | (struct parser_sizes): Deleted field long_len. 299 | (parser_init): Set short_opts to NULL, unless ARGP_LONG_ONLY is 300 | used. 301 | (classify_arg): New function. 302 | (parser_parse_next): Don't use getopt_long(). 303 | 304 | 2000-11-27 Niels Möller 305 | 306 | * argp-help.c (argp_doc): Use the name strndup, not 307 | __strndup. That probably breaks glibc builds. 308 | 309 | 2000-11-27 Niels Möller 310 | 311 | * argp-test.c (asprintf): Bug fix. 312 | 313 | * argp.h: Dummy definition of __THROW. 314 | 315 | * argp-test.c: Fixed asprintf implementation. 316 | 317 | * argp-parse.c (__argp_usage, __option_is_short, 318 | __option_is_end): Define these function, in case the user isn't 319 | inlining them. 320 | 321 | * argp-help.c: #define __mempcpy if needed. Use unsigned 322 | arguments to the ctype macros. Handle systems where 323 | program_invocation_name and program_invocation_short_name doesn't 324 | exist. 325 | * argp-help.c (short_program_name): New function. 326 | 327 | * Makefile.am: Use @LIBOBJS@ when building test program. 328 | 329 | * configure.in: Check for getopt_long. Substitute 330 | LIBOBJS. Add -I$srcdir to CPPFLAGS. 331 | 332 | * src/argp: Added getopt.h, getopt.c and getopt1.c, which are 333 | needed for separate compilation of argp. 334 | 335 | 2000-11-27 Niels Möller 336 | 337 | * Updated argp from glibc-2.2. 338 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # From glibc 2 | 3 | # Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc. 4 | # This file is part of the GNU C Library. 5 | 6 | # The GNU C Library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Library General Public License as 8 | # published by the Free Software Foundation; either version 2 of the 9 | # License, or (at your option) any later version. 10 | 11 | # The GNU C Library is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | # Library General Public License for more details. 15 | 16 | # You should have received a copy of the GNU Library General Public 17 | # License along with the GNU C Library; see the file COPYING.LIB. If 18 | # not, write to the Free Software Foundation, Inc., 19 | # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | 21 | AUTOMAKE_OPTIONS = foreign 22 | SUBDIRS = . testsuite 23 | 24 | LIBOBJS = @LIBOBJS@ 25 | 26 | noinst_LIBRARIES = libargp.a 27 | noinst_PROGRAMS = argp-test 28 | noinst_HEADERS = argp.h argp-fmtstream.h argp-namefrob.h # argp-comp.h 29 | 30 | EXTRA_DIST = mempcpy.c strchrnul.c strndup.c Versions 31 | 32 | # Leaves out argp-fs-xinl.c and argp-xinl.c 33 | libargp_a_SOURCES = argp-ba.c argp-eexst.c argp-fmtstream.c \ 34 | argp-help.c argp-parse.c argp-pv.c \ 35 | argp-pvh.c 36 | 37 | libargp_a_LIBADD = $(LIBOBJS) 38 | 39 | argp_test_LDADD = libargp.a 40 | 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # argp-standalone 2 | 3 | This is a continuation of [Niels Möller](https://www.lysator.liu.se/~nisse/)'s 4 | work on an argp library for systems which don't provide one themselves (most 5 | non-GNU ones). 6 | 7 | After noticing issues with executables built against argp-standalone 1.3, I 8 | decided to fork it and continue the effort. 9 | 10 | This repository is the result of making a timeline with releases 1.0 to 1.3 11 | (obtained from [here](https://www.lysator.liu.se/~nisse/misc/)) of the original 12 | argp-standalone, copying files from glibc 2.33 and fixing them up for 13 | compatibility, and finally some general clean up. I commited many trivial 14 | changes from the glibc version in order to make updating easier. 15 | 16 | It is my expectation that this library will be useful to others. Feel free to 17 | open an issue or make a PR. 18 | 19 | ## License 20 | 21 | Since this repository is based on GNU C Library source code and changes from 22 | Niels and collaborators, it is licensed primarily under the GNU Lesser General 23 | Public License, version 2.1 or later (SPDX: `LGPL-2.1-or-later`). 24 | -------------------------------------------------------------------------------- /Versions: -------------------------------------------------------------------------------- 1 | libc { 2 | GLIBC_2.1 { 3 | # variables in normal name space 4 | argp_err_exit_status; argp_program_bug_address; argp_program_version; 5 | argp_program_version_hook; 6 | 7 | # a* 8 | argp_error; argp_failure; argp_help; argp_parse; argp_state_help; 9 | argp_usage; 10 | 11 | # kludge for recursive argp callers that know the magic. 12 | _argp_unlock_xxx; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /acconfig.h: -------------------------------------------------------------------------------- 1 | /* Global variables needed by argp */ 2 | #undef HAVE_PROGRAM_INVOCATION_NAME 3 | #undef HAVE_PROGRAM_INVOCATION_SHORT_NAME 4 | -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | dnl Try to detect the type of the third arg to getsockname() et al 2 | AC_DEFUN([LSH_TYPE_SOCKLEN_T], 3 | [AH_TEMPLATE([socklen_t], [Length type used by getsockopt]) 4 | AC_CACHE_CHECK([for socklen_t in sys/socket.h], ac_cv_type_socklen_t, 5 | [AC_EGREP_HEADER(socklen_t, sys/socket.h, 6 | [ac_cv_type_socklen_t=yes], [ac_cv_type_socklen_t=no])]) 7 | if test $ac_cv_type_socklen_t = no; then 8 | AC_MSG_CHECKING(for AIX) 9 | AC_EGREP_CPP(yes, [ 10 | #ifdef _AIX 11 | yes 12 | #endif 13 | ],[ 14 | AC_MSG_RESULT(yes) 15 | AC_DEFINE(socklen_t, size_t) 16 | ],[ 17 | AC_MSG_RESULT(no) 18 | AC_DEFINE(socklen_t, int) 19 | ]) 20 | fi 21 | ]) 22 | 23 | dnl LSH_PATH_ADD(path-id, directory) 24 | AC_DEFUN([LSH_PATH_ADD], 25 | [AC_MSG_CHECKING($2) 26 | ac_exists=no 27 | if test -d "$2/." ; then 28 | ac_real_dir=`cd $2 && pwd` 29 | if test -n "$ac_real_dir" ; then 30 | ac_exists=yes 31 | for old in $1_REAL_DIRS ; do 32 | ac_found=no 33 | if test x$ac_real_dir = x$old ; then 34 | ac_found=yes; 35 | break; 36 | fi 37 | done 38 | if test $ac_found = yes ; then 39 | AC_MSG_RESULT(already added) 40 | else 41 | AC_MSG_RESULT(added) 42 | # LDFLAGS="$LDFLAGS -L $2" 43 | $1_REAL_DIRS="$ac_real_dir [$]$1_REAL_DIRS" 44 | $1_DIRS="$2 [$]$1_DIRS" 45 | fi 46 | fi 47 | fi 48 | if test $ac_exists = no ; then 49 | AC_MSG_RESULT(not found) 50 | fi 51 | ]) 52 | 53 | dnl LSH_RPATH_ADD(dir) 54 | AC_DEFUN([LSH_RPATH_ADD], [LSH_PATH_ADD(RPATH_CANDIDATE, $1)]) 55 | 56 | dnl LSH_RPATH_INIT(candidates) 57 | AC_DEFUN([LSH_RPATH_INIT], 58 | [AC_MSG_CHECKING([for -R flag]) 59 | RPATHFLAG='' 60 | case `uname -sr` in 61 | OSF1\ V4.*) 62 | RPATHFLAG="-rpath " 63 | ;; 64 | IRIX\ 6.*) 65 | RPATHFLAG="-rpath " 66 | ;; 67 | IRIX\ 5.*) 68 | RPATHFLAG="-rpath " 69 | ;; 70 | SunOS\ 5.*) 71 | if test "$TCC" = "yes"; then 72 | # tcc doesn't know about -R 73 | RPATHFLAG="-Wl,-R," 74 | else 75 | RPATHFLAG=-R 76 | fi 77 | ;; 78 | Linux\ 2.*) 79 | RPATHFLAG="-Wl,-rpath," 80 | ;; 81 | *) 82 | : 83 | ;; 84 | esac 85 | 86 | if test x$RPATHFLAG = x ; then 87 | AC_MSG_RESULT(none) 88 | else 89 | AC_MSG_RESULT([using $RPATHFLAG]) 90 | fi 91 | 92 | RPATH_CANDIDATE_REAL_DIRS='' 93 | RPATH_CANDIDATE_DIRS='' 94 | 95 | AC_MSG_RESULT([Searching for libraries]) 96 | 97 | for d in $1 ; do 98 | LSH_RPATH_ADD($d) 99 | done 100 | ]) 101 | 102 | dnl Try to execute a main program, and if it fails, try adding some 103 | dnl -R flag. 104 | dnl LSH_RPATH_FIX 105 | AC_DEFUN([LSH_RPATH_FIX], 106 | [if test $cross_compiling = no -a "x$RPATHFLAG" != x ; then 107 | ac_success=no 108 | AC_TRY_RUN([int main(int argc, char **argv) { return 0; }], 109 | ac_success=yes, ac_success=no, :) 110 | 111 | if test $ac_success = no ; then 112 | AC_MSG_CHECKING([Running simple test program failed. Trying -R flags]) 113 | dnl echo RPATH_CANDIDATE_DIRS = $RPATH_CANDIDATE_DIRS 114 | ac_remaining_dirs='' 115 | ac_rpath_save_LDFLAGS="$LDFLAGS" 116 | for d in $RPATH_CANDIDATE_DIRS ; do 117 | if test $ac_success = yes ; then 118 | ac_remaining_dirs="$ac_remaining_dirs $d" 119 | else 120 | LDFLAGS="$RPATHFLAG$d $LDFLAGS" 121 | dnl echo LDFLAGS = $LDFLAGS 122 | AC_TRY_RUN([int main(int argc, char **argv) { return 0; }], 123 | [ac_success=yes 124 | ac_rpath_save_LDFLAGS="$LDFLAGS" 125 | AC_MSG_RESULT([adding $RPATHFLAG$d]) 126 | ], 127 | [ac_remaining_dirs="$ac_remaining_dirs $d"], :) 128 | LDFLAGS="$ac_rpath_save_LDFLAGS" 129 | fi 130 | done 131 | RPATH_CANDIDATE_DIRS=$ac_remaining_dirs 132 | fi 133 | if test $ac_success = no ; then 134 | AC_MSG_RESULT(failed) 135 | fi 136 | fi 137 | ]) 138 | 139 | dnl Like AC_CHECK_LIB, but uses $KRB_LIBS rather than $LIBS. 140 | dnl LSH_CHECK_KRB_LIB(LIBRARY, FUNCTION, [, ACTION-IF-FOUND [, 141 | dnl ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]]) 142 | 143 | AC_DEFUN([LSH_CHECK_KRB_LIB], 144 | [AC_CHECK_LIB([$1], [$2], 145 | ifelse([$3], , 146 | [[ac_tr_lib=HAVE_LIB`echo $1 | sed -e 's/[^a-zA-Z0-9_]/_/g' \ 147 | -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` 148 | AC_DEFINE_UNQUOTED($ac_tr_lib) 149 | KRB_LIBS="-l$1 $KRB_LIBS" 150 | ]], [$3]), 151 | ifelse([$4], , , [$4 152 | ])dnl 153 | , [$5 $KRB_LIBS]) 154 | ]) 155 | 156 | dnl LSH_LIB_ARGP(ACTION-IF-OK, ACTION-IF-BAD) 157 | AC_DEFUN([LSH_LIB_ARGP], 158 | [ ac_argp_save_LIBS="$LIBS" 159 | ac_argp_save_LDFLAGS="$LDFLAGS" 160 | ac_argp_ok=no 161 | # First check if we can link with argp. 162 | AC_SEARCH_LIBS(argp_parse, argp, 163 | [ LSH_RPATH_FIX 164 | AC_CACHE_CHECK([for working argp], 165 | lsh_cv_lib_argp_works, 166 | [ AC_TRY_RUN( 167 | [#include 168 | #include 169 | 170 | static const struct argp_option 171 | options[] = 172 | { 173 | { NULL, 0, NULL, 0, NULL, 0 } 174 | }; 175 | 176 | struct child_state 177 | { 178 | int n; 179 | }; 180 | 181 | static error_t 182 | child_parser(int key, char *arg, struct argp_state *state) 183 | { 184 | struct child_state *input = (struct child_state *) state->input; 185 | 186 | switch(key) 187 | { 188 | default: 189 | return ARGP_ERR_UNKNOWN; 190 | case ARGP_KEY_END: 191 | if (!input->n) 192 | input->n = 1; 193 | break; 194 | } 195 | return 0; 196 | } 197 | 198 | const struct argp child_argp = 199 | { 200 | options, 201 | child_parser, 202 | NULL, NULL, NULL, NULL, NULL 203 | }; 204 | 205 | struct main_state 206 | { 207 | struct child_state child; 208 | int m; 209 | }; 210 | 211 | static error_t 212 | main_parser(int key, char *arg, struct argp_state *state) 213 | { 214 | struct main_state *input = (struct main_state *) state->input; 215 | 216 | switch(key) 217 | { 218 | default: 219 | return ARGP_ERR_UNKNOWN; 220 | case ARGP_KEY_INIT: 221 | state->child_inputs[0] = &input->child; 222 | break; 223 | case ARGP_KEY_END: 224 | if (!input->m) 225 | input->m = input->child.n; 226 | 227 | break; 228 | } 229 | return 0; 230 | } 231 | 232 | static const struct argp_child 233 | main_children[] = 234 | { 235 | { &child_argp, 0, "", 0 }, 236 | { NULL, 0, NULL, 0} 237 | }; 238 | 239 | static const struct argp 240 | main_argp = 241 | { options, main_parser, 242 | NULL, 243 | NULL, 244 | main_children, 245 | NULL, NULL 246 | }; 247 | 248 | int main(int argc, char **argv) 249 | { 250 | struct main_state input = { { 0 }, 0 }; 251 | char *v[2] = { "foo", NULL }; 252 | 253 | argp_parse(&main_argp, 1, v, 0, NULL, &input); 254 | 255 | if ( (input.m == 1) && (input.child.n == 1) ) 256 | return 0; 257 | else 258 | return 1; 259 | } 260 | ], lsh_cv_lib_argp_works=yes, 261 | lsh_cv_lib_argp_works=no, 262 | lsh_cv_lib_argp_works=no)]) 263 | 264 | if test x$lsh_cv_lib_argp_works = xyes ; then 265 | ac_argp_ok=yes 266 | else 267 | # Reset link flags 268 | LIBS="$ac_argp_save_LIBS" 269 | LDFLAGS="$ac_argp_save_LDFLAGS" 270 | fi]) 271 | 272 | if test x$ac_argp_ok = xyes ; then 273 | ifelse([$1],, true, [$1]) 274 | else 275 | ifelse([$2],, true, [$2]) 276 | fi 277 | ]) 278 | 279 | dnl LSH_GCC_ATTRIBUTES 280 | dnl Check for gcc's __attribute__ construction 281 | 282 | AC_DEFUN([LSH_GCC_ATTRIBUTES], 283 | [AC_CACHE_CHECK(for __attribute__, 284 | lsh_cv_c_attribute, 285 | [ AC_TRY_COMPILE([ 286 | #include 287 | static void foo(void) __attribute__ ((noreturn)); 288 | 289 | static void __attribute__ ((noreturn)) 290 | foo(void) 291 | { 292 | exit(1); 293 | } 294 | ], 295 | [ 296 | ], 297 | lsh_cv_c_attribute=yes, 298 | lsh_cv_c_attribute=no)]) 299 | 300 | AH_TEMPLATE([HAVE_GCC_ATTRIBUTE], [Define if the compiler understands __attribute__]) 301 | if test "x$lsh_cv_c_attribute" = "xyes"; then 302 | AC_DEFINE(HAVE_GCC_ATTRIBUTE) 303 | fi 304 | 305 | AH_BOTTOM( 306 | [#if __GNUC__ && HAVE_GCC_ATTRIBUTE 307 | # define NORETURN __attribute__ ((__noreturn__)) 308 | # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) 309 | # define UNUSED __attribute__ ((__unused__)) 310 | #else 311 | # define NORETURN 312 | # define PRINTF_STYLE(f, a) 313 | # define UNUSED 314 | #endif 315 | ])]) 316 | 317 | AC_DEFUN([LSH_GCC_FUNCTION_NAME], 318 | [# Check for gcc's __FUNCTION__ variable 319 | AH_TEMPLATE([HAVE_GCC_FUNCTION], 320 | [Define if the compiler understands __FUNCTION__]) 321 | AH_BOTTOM( 322 | [#if HAVE_GCC_FUNCTION 323 | # define FUNCTION_NAME __FUNCTION__ 324 | #else 325 | # define FUNCTION_NAME "Unknown" 326 | #endif 327 | ]) 328 | 329 | AC_CACHE_CHECK(for __FUNCTION__, 330 | lsh_cv_c_FUNCTION, 331 | [ AC_TRY_COMPILE(, 332 | [ #if __GNUC__ == 3 333 | # error __FUNCTION__ is broken in gcc-3 334 | #endif 335 | void foo(void) { char c = __FUNCTION__[0]; } ], 336 | lsh_cv_c_FUNCTION=yes, 337 | lsh_cv_c_FUNCTION=no)]) 338 | 339 | if test "x$lsh_cv_c_FUNCTION" = "xyes"; then 340 | AC_DEFINE(HAVE_GCC_FUNCTION) 341 | fi 342 | ]) 343 | 344 | # Check for alloca, and include the standard blurb in config.h 345 | AC_DEFUN([LSH_FUNC_ALLOCA], 346 | [AC_FUNC_ALLOCA 347 | AH_BOTTOM( 348 | [/* AIX requires this to be the first thing in the file. */ 349 | #ifndef __GNUC__ 350 | # if HAVE_ALLOCA_H 351 | # include 352 | # else 353 | # ifdef _AIX 354 | #pragma alloca 355 | # else 356 | # ifndef alloca /* predefined by HP cc +Olibcalls */ 357 | char *alloca (); 358 | # endif 359 | # endif 360 | # endif 361 | #else /* defined __GNUC__ */ 362 | # if HAVE_ALLOCA_H 363 | # include 364 | # endif 365 | #endif 366 | ])]) 367 | 368 | AC_DEFUN([LSH_FUNC_STRERROR], 369 | [AC_CHECK_FUNCS(strerror) 370 | AH_BOTTOM( 371 | [#if HAVE_STRERROR 372 | #define STRERROR strerror 373 | #else 374 | #define STRERROR(x) (sys_errlist[x]) 375 | #endif 376 | ])]) 377 | 378 | AC_DEFUN([LSH_FUNC_STRSIGNAL], 379 | [AC_CHECK_FUNCS(strsignal) 380 | AC_CHECK_DECLS([sys_siglist, _sys_siglist]) 381 | AH_BOTTOM( 382 | [#if HAVE_STRSIGNAL 383 | # define STRSIGNAL strsignal 384 | #else /* !HAVE_STRSIGNAL */ 385 | # if HAVE_DECL_SYS_SIGLIST 386 | # define STRSIGNAL(x) (sys_siglist[x]) 387 | # else 388 | # if HAVE_DECL__SYS_SIGLIST 389 | # define STRSIGNAL(x) (_sys_siglist[x]) 390 | # else 391 | # define STRSIGNAL(x) "Unknown signal" 392 | # if __GNUC__ 393 | # warning Using dummy STRSIGNAL 394 | # endif 395 | # endif 396 | # endif 397 | #endif /* !HAVE_STRSIGNAL */ 398 | ])]) 399 | 400 | dnl @synopsis AX_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEADERS-TO-CHECK])] 401 | dnl 402 | dnl the "ISO C9X: 7.18 Integer types " section requires the 403 | dnl existence of an include file that defines a set of 404 | dnl typedefs, especially uint8_t,int32_t,uintptr_t. 405 | dnl Many older installations will not provide this file, but some will 406 | dnl have the very same definitions in . In other enviroments 407 | dnl we can use the inet-types in which would define the 408 | dnl typedefs int8_t and u_int8_t respectivly. 409 | dnl 410 | dnl This macros will create a local "_stdint.h" or the headerfile given as 411 | dnl an argument. In many cases that file will just "#include " 412 | dnl or "#include ", while in other environments it will provide 413 | dnl the set of basic 'stdint's definitions/typedefs: 414 | dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t 415 | dnl int_least32_t.. int_fast32_t.. intmax_t 416 | dnl which may or may not rely on the definitions of other files, 417 | dnl or using the AC_CHECK_SIZEOF macro to determine the actual 418 | dnl sizeof each type. 419 | dnl 420 | dnl if your header files require the stdint-types you will want to create an 421 | dnl installable file mylib-int.h that all your other installable header 422 | dnl may include. So if you have a library package named "mylib", just use 423 | dnl AX_CREATE_STDINT_H(mylib-int.h) 424 | dnl in configure.ac and go to install that very header file in Makefile.am 425 | dnl along with the other headers (mylib.h) - and the mylib-specific headers 426 | dnl can simply use "#include " to obtain the stdint-types. 427 | dnl 428 | dnl Remember, if the system already had a valid , the generated 429 | dnl file will include it directly. No need for fuzzy HAVE_STDINT_H things... 430 | dnl 431 | dnl @, (status: used on new platforms) (see http://ac-archive.sf.net/gstdint/) 432 | dnl @version $Id: acinclude.m4,v 1.18 2004/02/07 14:21:04 nisse Exp $ 433 | dnl @author Guido Draheim 434 | 435 | AC_DEFUN([AX_CREATE_STDINT_H], 436 | [# ------ AX CREATE STDINT H ------------------------------------- 437 | AC_MSG_CHECKING([for stdint types]) 438 | ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` 439 | # try to shortcircuit - if the default include path of the compiler 440 | # can find a "stdint.h" header then we assume that all compilers can. 441 | AC_CACHE_VAL([ac_cv_header_stdint_t],[ 442 | old_CXXFLAGS="$CXXFLAGS" ; CXXFLAGS="" 443 | old_CPPFLAGS="$CPPFLAGS" ; CPPFLAGS="" 444 | old_CFLAGS="$CFLAGS" ; CFLAGS="" 445 | AC_TRY_COMPILE([#include ],[int_least32_t v = 0;], 446 | [ac_cv_stdint_result="(assuming C99 compatible system)" 447 | ac_cv_header_stdint_t="stdint.h"; ], 448 | [ac_cv_header_stdint_t=""]) 449 | CXXFLAGS="$old_CXXFLAGS" 450 | CPPFLAGS="$old_CPPFLAGS" 451 | CFLAGS="$old_CFLAGS" ]) 452 | 453 | v="... $ac_cv_header_stdint_h" 454 | if test "$ac_stdint_h" = "stdint.h" ; then 455 | AC_MSG_RESULT([(are you sure you want them in ./stdint.h?)]) 456 | elif test "$ac_stdint_h" = "inttypes.h" ; then 457 | AC_MSG_RESULT([(are you sure you want them in ./inttypes.h?)]) 458 | elif test "_$ac_cv_header_stdint_t" = "_" ; then 459 | AC_MSG_RESULT([(putting them into $ac_stdint_h)$v]) 460 | else 461 | ac_cv_header_stdint="$ac_cv_header_stdint_t" 462 | AC_MSG_RESULT([$ac_cv_header_stdint (shortcircuit)]) 463 | fi 464 | 465 | if test "_$ac_cv_header_stdint_t" = "_" ; then # can not shortcircuit.. 466 | 467 | dnl .....intro message done, now do a few system checks..... 468 | dnl btw, all CHECK_TYPE macros do automatically "DEFINE" a type, therefore 469 | dnl we use the autoconf implementation detail _AC CHECK_TYPE_NEW instead 470 | 471 | inttype_headers=`echo $2 | sed -e 's/,/ /g'` 472 | 473 | ac_cv_stdint_result="(no helpful system typedefs seen)" 474 | AC_CACHE_CHECK([for stdint uintptr_t], [ac_cv_header_stdint_x],[ 475 | ac_cv_header_stdint_x="" # the 1997 typedefs (inttypes.h) 476 | AC_MSG_RESULT([(..)]) 477 | for i in stdint.h inttypes.h sys/inttypes.h $inttype_headers ; do 478 | unset ac_cv_type_uintptr_t 479 | unset ac_cv_type_uint64_t 480 | _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl 481 | continue,[#include <$i>]) 482 | AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) 483 | ac_cv_stdint_result="(seen uintptr_t$and64 in $i)" 484 | break; 485 | done 486 | AC_MSG_CHECKING([for stdint uintptr_t]) 487 | ]) 488 | 489 | if test "_$ac_cv_header_stdint_x" = "_" ; then 490 | AC_CACHE_CHECK([for stdint uint32_t], [ac_cv_header_stdint_o],[ 491 | ac_cv_header_stdint_o="" # the 1995 typedefs (sys/inttypes.h) 492 | AC_MSG_RESULT([(..)]) 493 | for i in inttypes.h sys/inttypes.h stdint.h $inttype_headers ; do 494 | unset ac_cv_type_uint32_t 495 | unset ac_cv_type_uint64_t 496 | AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl 497 | continue,[#include <$i>]) 498 | AC_CHECK_TYPE(uint64_t,[and64="/uint64_t"],[and64=""],[#include<$i>]) 499 | ac_cv_stdint_result="(seen uint32_t$and64 in $i)" 500 | break; 501 | done 502 | AC_MSG_CHECKING([for stdint uint32_t]) 503 | ]) 504 | fi 505 | 506 | if test "_$ac_cv_header_stdint_x" = "_" ; then 507 | if test "_$ac_cv_header_stdint_o" = "_" ; then 508 | AC_CACHE_CHECK([for stdint u_int32_t], [ac_cv_header_stdint_u],[ 509 | ac_cv_header_stdint_u="" # the BSD typedefs (sys/types.h) 510 | AC_MSG_RESULT([(..)]) 511 | for i in sys/types.h inttypes.h sys/inttypes.h $inttype_headers ; do 512 | unset ac_cv_type_u_int32_t 513 | unset ac_cv_type_u_int64_t 514 | AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl 515 | continue,[#include <$i>]) 516 | AC_CHECK_TYPE(u_int64_t,[and64="/u_int64_t"],[and64=""],[#include<$i>]) 517 | ac_cv_stdint_result="(seen u_int32_t$and64 in $i)" 518 | break; 519 | done 520 | AC_MSG_CHECKING([for stdint u_int32_t]) 521 | ]) 522 | fi fi 523 | 524 | dnl if there was no good C99 header file, do some typedef checks... 525 | if test "_$ac_cv_header_stdint_x" = "_" ; then 526 | AC_MSG_CHECKING([for stdint datatype model]) 527 | AC_MSG_RESULT([(..)]) 528 | AC_CHECK_SIZEOF(char) 529 | AC_CHECK_SIZEOF(short) 530 | AC_CHECK_SIZEOF(int) 531 | AC_CHECK_SIZEOF(long) 532 | AC_CHECK_SIZEOF(void*) 533 | ac_cv_stdint_char_model="" 534 | ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_char" 535 | ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_short" 536 | ac_cv_stdint_char_model="$ac_cv_stdint_char_model$ac_cv_sizeof_int" 537 | ac_cv_stdint_long_model="" 538 | ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_int" 539 | ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_long" 540 | ac_cv_stdint_long_model="$ac_cv_stdint_long_model$ac_cv_sizeof_voidp" 541 | name="$ac_cv_stdint_long_model" 542 | case "$ac_cv_stdint_char_model/$ac_cv_stdint_long_model" in 543 | 122/242) name="$name, IP16 (standard 16bit machine)" ;; 544 | 122/244) name="$name, LP32 (standard 32bit mac/win)" ;; 545 | 122/*) name="$name (unusual int16 model)" ;; 546 | 124/444) name="$name, ILP32 (standard 32bit unixish)" ;; 547 | 124/488) name="$name, LP64 (standard 64bit unixish)" ;; 548 | 124/448) name="$name, LLP64 (unusual 64bit unixish)" ;; 549 | 124/*) name="$name (unusual int32 model)" ;; 550 | 128/888) name="$name, ILP64 (unusual 64bit numeric)" ;; 551 | 128/*) name="$name (unusual int64 model)" ;; 552 | 222/*|444/*) name="$name (unusual dsptype)" ;; 553 | *) name="$name (very unusal model)" ;; 554 | esac 555 | AC_MSG_RESULT([combined for stdint datatype model... $name]) 556 | fi 557 | 558 | if test "_$ac_cv_header_stdint_x" != "_" ; then 559 | ac_cv_header_stdint="$ac_cv_header_stdint_x" 560 | elif test "_$ac_cv_header_stdint_o" != "_" ; then 561 | ac_cv_header_stdint="$ac_cv_header_stdint_o" 562 | elif test "_$ac_cv_header_stdint_u" != "_" ; then 563 | ac_cv_header_stdint="$ac_cv_header_stdint_u" 564 | else 565 | ac_cv_header_stdint="stddef.h" 566 | fi 567 | 568 | AC_MSG_CHECKING([for extra inttypes in chosen header]) 569 | AC_MSG_RESULT([($ac_cv_header_stdint)]) 570 | dnl see if int_least and int_fast types are present in _this_ header. 571 | unset ac_cv_type_int_least32_t 572 | unset ac_cv_type_int_fast32_t 573 | AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) 574 | AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) 575 | AC_CHECK_TYPE(intmax_t,,,[#include <$ac_cv_header_stdint>]) 576 | 577 | fi # shortcircut to system "stdint.h" 578 | # ------------------ PREPARE VARIABLES ------------------------------ 579 | if test "$GCC" = "yes" ; then 580 | ac_cv_stdint_message="using gnu compiler "`$CC --version | head -1` 581 | else 582 | ac_cv_stdint_message="using $CC" 583 | fi 584 | 585 | AC_MSG_RESULT([make use of $ac_cv_header_stdint in $ac_stdint_h dnl 586 | $ac_cv_stdint_result]) 587 | 588 | # ----------------- DONE inttypes.h checks START header ------------- 589 | AC_CONFIG_COMMANDS([$ac_stdint_h],[ 590 | AC_MSG_NOTICE(creating $ac_stdint_h : $_ac_stdint_h) 591 | ac_stdint=$tmp/_stdint.h 592 | 593 | echo "#ifndef" $_ac_stdint_h >$ac_stdint 594 | echo "#define" $_ac_stdint_h "1" >>$ac_stdint 595 | echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint 596 | echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint 597 | echo "/* generated $ac_cv_stdint_message */" >>$ac_stdint 598 | if test "_$ac_cv_header_stdint_t" != "_" ; then 599 | echo "#define _STDINT_HAVE_STDINT_H" "1" >>$ac_stdint 600 | fi 601 | 602 | cat >>$ac_stdint < 608 | #else 609 | #include 610 | 611 | /* .................... configured part ............................ */ 612 | 613 | STDINT_EOF 614 | 615 | echo "/* whether we have a C99 compatible stdint header file */" >>$ac_stdint 616 | if test "_$ac_cv_header_stdint_x" != "_" ; then 617 | ac_header="$ac_cv_header_stdint_x" 618 | echo "#define _STDINT_HEADER_INTPTR" '"'"$ac_header"'"' >>$ac_stdint 619 | else 620 | echo "/* #undef _STDINT_HEADER_INTPTR */" >>$ac_stdint 621 | fi 622 | 623 | echo "/* whether we have a C96 compatible inttypes header file */" >>$ac_stdint 624 | if test "_$ac_cv_header_stdint_o" != "_" ; then 625 | ac_header="$ac_cv_header_stdint_o" 626 | echo "#define _STDINT_HEADER_UINT32" '"'"$ac_header"'"' >>$ac_stdint 627 | else 628 | echo "/* #undef _STDINT_HEADER_UINT32 */" >>$ac_stdint 629 | fi 630 | 631 | echo "/* whether we have a BSD compatible inet types header */" >>$ac_stdint 632 | if test "_$ac_cv_header_stdint_u" != "_" ; then 633 | ac_header="$ac_cv_header_stdint_u" 634 | echo "#define _STDINT_HEADER_U_INT32" '"'"$ac_header"'"' >>$ac_stdint 635 | else 636 | echo "/* #undef _STDINT_HEADER_U_INT32 */" >>$ac_stdint 637 | fi 638 | 639 | echo "" >>$ac_stdint 640 | 641 | if test "_$ac_header" != "_" ; then if test "$ac_header" != "stddef.h" ; then 642 | echo "#include <$ac_header>" >>$ac_stdint 643 | echo "" >>$ac_stdint 644 | fi fi 645 | 646 | echo "/* which 64bit typedef has been found */" >>$ac_stdint 647 | if test "$ac_cv_type_uint64_t" = "yes" ; then 648 | echo "#define _STDINT_HAVE_UINT64_T" "1" >>$ac_stdint 649 | else 650 | echo "/* #undef _STDINT_HAVE_UINT64_T */" >>$ac_stdint 651 | fi 652 | if test "$ac_cv_type_u_int64_t" = "yes" ; then 653 | echo "#define _STDINT_HAVE_U_INT64_T" "1" >>$ac_stdint 654 | else 655 | echo "/* #undef _STDINT_HAVE_U_INT64_T */" >>$ac_stdint 656 | fi 657 | echo "" >>$ac_stdint 658 | 659 | echo "/* which type model has been detected */" >>$ac_stdint 660 | if test "_$ac_cv_stdint_char_model" != "_" ; then 661 | echo "#define _STDINT_CHAR_MODEL" "$ac_cv_stdint_char_model" >>$ac_stdint 662 | echo "#define _STDINT_LONG_MODEL" "$ac_cv_stdint_long_model" >>$ac_stdint 663 | else 664 | echo "/* #undef _STDINT_CHAR_MODEL // skipped */" >>$ac_stdint 665 | echo "/* #undef _STDINT_LONG_MODEL // skipped */" >>$ac_stdint 666 | fi 667 | echo "" >>$ac_stdint 668 | 669 | echo "/* whether int_least types were detected */" >>$ac_stdint 670 | if test "$ac_cv_type_int_least32_t" = "yes"; then 671 | echo "#define _STDINT_HAVE_INT_LEAST32_T" "1" >>$ac_stdint 672 | else 673 | echo "/* #undef _STDINT_HAVE_INT_LEAST32_T */" >>$ac_stdint 674 | fi 675 | echo "/* whether int_fast types were detected */" >>$ac_stdint 676 | if test "$ac_cv_type_int_fast32_t" = "yes"; then 677 | echo "#define _STDINT_HAVE_INT_FAST32_T" "1" >>$ac_stdint 678 | else 679 | echo "/* #undef _STDINT_HAVE_INT_FAST32_T */" >>$ac_stdint 680 | fi 681 | echo "/* whether intmax_t type was detected */" >>$ac_stdint 682 | if test "$ac_cv_type_intmax_t" = "yes"; then 683 | echo "#define _STDINT_HAVE_INTMAX_T" "1" >>$ac_stdint 684 | else 685 | echo "/* #undef _STDINT_HAVE_INTMAX_T */" >>$ac_stdint 686 | fi 687 | echo "" >>$ac_stdint 688 | 689 | cat >>$ac_stdint <= 199901L 746 | #define _HAVE_UINT64_T 747 | typedef long long int64_t; 748 | typedef unsigned long long uint64_t; 749 | 750 | #elif !defined __STRICT_ANSI__ 751 | #if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ 752 | #define _HAVE_UINT64_T 753 | typedef __int64 int64_t; 754 | typedef unsigned __int64 uint64_t; 755 | 756 | #elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ 757 | /* note: all ELF-systems seem to have loff-support which needs 64-bit */ 758 | #if !defined _NO_LONGLONG 759 | #define _HAVE_UINT64_T 760 | typedef long long int64_t; 761 | typedef unsigned long long uint64_t; 762 | #endif 763 | 764 | #elif defined __alpha || (defined __mips && defined _ABIN32) 765 | #if !defined _NO_LONGLONG 766 | typedef long int64_t; 767 | typedef unsigned long uint64_t; 768 | #endif 769 | /* compiler/cpu type to define int64_t */ 770 | #endif 771 | #endif 772 | #endif 773 | 774 | #if defined _STDINT_HAVE_U_INT_TYPES 775 | /* int8_t int16_t int32_t defined by inet code, redeclare the u_intXX types */ 776 | typedef u_int8_t uint8_t; 777 | typedef u_int16_t uint16_t; 778 | typedef u_int32_t uint32_t; 779 | 780 | /* glibc compatibility */ 781 | #ifndef __int8_t_defined 782 | #define __int8_t_defined 783 | #endif 784 | #endif 785 | 786 | #ifdef _STDINT_NEED_INT_MODEL_T 787 | /* we must guess all the basic types. Apart from byte-adressable system, */ 788 | /* there a few 32-bit-only dsp-systems that we guard with BYTE_MODEL 8-} */ 789 | /* (btw, those nibble-addressable systems are way off, or so we assume) */ 790 | 791 | dnl /* have a look at "64bit and data size neutrality" at */ 792 | dnl /* http://unix.org/version2/whatsnew/login_64bit.html */ 793 | dnl /* (the shorthand "ILP" types always have a "P" part) */ 794 | 795 | #if defined _STDINT_BYTE_MODEL 796 | #if _STDINT_LONG_MODEL+0 == 242 797 | /* 2:4:2 = IP16 = a normal 16-bit system */ 798 | typedef unsigned char uint8_t; 799 | typedef unsigned short uint16_t; 800 | typedef unsigned long uint32_t; 801 | #ifndef __int8_t_defined 802 | #define __int8_t_defined 803 | typedef char int8_t; 804 | typedef short int16_t; 805 | typedef long int32_t; 806 | #endif 807 | #elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL == 444 808 | /* 2:4:4 = LP32 = a 32-bit system derived from a 16-bit */ 809 | /* 4:4:4 = ILP32 = a normal 32-bit system */ 810 | typedef unsigned char uint8_t; 811 | typedef unsigned short uint16_t; 812 | typedef unsigned int uint32_t; 813 | #ifndef __int8_t_defined 814 | #define __int8_t_defined 815 | typedef char int8_t; 816 | typedef short int16_t; 817 | typedef int int32_t; 818 | #endif 819 | #elif _STDINT_LONG_MODEL+0 == 484 || _STDINT_LONG_MODEL+0 == 488 820 | /* 4:8:4 = IP32 = a 32-bit system prepared for 64-bit */ 821 | /* 4:8:8 = LP64 = a normal 64-bit system */ 822 | typedef unsigned char uint8_t; 823 | typedef unsigned short uint16_t; 824 | typedef unsigned int uint32_t; 825 | #ifndef __int8_t_defined 826 | #define __int8_t_defined 827 | typedef char int8_t; 828 | typedef short int16_t; 829 | typedef int int32_t; 830 | #endif 831 | /* this system has a "long" of 64bit */ 832 | #ifndef _HAVE_UINT64_T 833 | #define _HAVE_UINT64_T 834 | typedef unsigned long uint64_t; 835 | typedef long int64_t; 836 | #endif 837 | #elif _STDINT_LONG_MODEL+0 == 448 838 | /* LLP64 a 64-bit system derived from a 32-bit system */ 839 | typedef unsigned char uint8_t; 840 | typedef unsigned short uint16_t; 841 | typedef unsigned int uint32_t; 842 | #ifndef __int8_t_defined 843 | #define __int8_t_defined 844 | typedef char int8_t; 845 | typedef short int16_t; 846 | typedef int int32_t; 847 | #endif 848 | /* assuming the system has a "long long" */ 849 | #ifndef _HAVE_UINT64_T 850 | #define _HAVE_UINT64_T 851 | typedef unsigned long long uint64_t; 852 | typedef long long int64_t; 853 | #endif 854 | #else 855 | #define _STDINT_NO_INT32_T 856 | #endif 857 | #else 858 | #define _STDINT_NO_INT8_T 859 | #define _STDINT_NO_INT32_T 860 | #endif 861 | #endif 862 | 863 | /* 864 | * quote from SunOS-5.8 sys/inttypes.h: 865 | * Use at your own risk. As of February 1996, the committee is squarely 866 | * behind the fixed sized types; the "least" and "fast" types are still being 867 | * discussed. The probability that the "fast" types may be removed before 868 | * the standard is finalized is high enough that they are not currently 869 | * implemented. 870 | */ 871 | 872 | #if defined _STDINT_NEED_INT_LEAST_T 873 | typedef int8_t int_least8_t; 874 | typedef int16_t int_least16_t; 875 | typedef int32_t int_least32_t; 876 | #ifdef _HAVE_UINT64_T 877 | typedef int64_t int_least64_t; 878 | #endif 879 | 880 | typedef uint8_t uint_least8_t; 881 | typedef uint16_t uint_least16_t; 882 | typedef uint32_t uint_least32_t; 883 | #ifdef _HAVE_UINT64_T 884 | typedef uint64_t uint_least64_t; 885 | #endif 886 | /* least types */ 887 | #endif 888 | 889 | #if defined _STDINT_NEED_INT_FAST_T 890 | typedef int8_t int_fast8_t; 891 | typedef int int_fast16_t; 892 | typedef int32_t int_fast32_t; 893 | #ifdef _HAVE_UINT64_T 894 | typedef int64_t int_fast64_t; 895 | #endif 896 | 897 | typedef uint8_t uint_fast8_t; 898 | typedef unsigned uint_fast16_t; 899 | typedef uint32_t uint_fast32_t; 900 | #ifdef _HAVE_UINT64_T 901 | typedef uint64_t uint_fast64_t; 902 | #endif 903 | /* fast types */ 904 | #endif 905 | 906 | #ifdef _STDINT_NEED_INTMAX_T 907 | #ifdef _HAVE_UINT64_T 908 | typedef int64_t intmax_t; 909 | typedef uint64_t uintmax_t; 910 | #else 911 | typedef long intmax_t; 912 | typedef unsigned long uintmax_t; 913 | #endif 914 | #endif 915 | 916 | #ifdef _STDINT_NEED_INTPTR_T 917 | #ifndef __intptr_t_defined 918 | #define __intptr_t_defined 919 | /* we encourage using "long" to store pointer values, never use "int" ! */ 920 | #if _STDINT_LONG_MODEL+0 == 242 || _STDINT_LONG_MODEL+0 == 484 921 | typedef unsinged int uintptr_t; 922 | typedef int intptr_t; 923 | #elif _STDINT_LONG_MODEL+0 == 244 || _STDINT_LONG_MODEL+0 == 444 924 | typedef unsigned long uintptr_t; 925 | typedef long intptr_t; 926 | #elif _STDINT_LONG_MODEL+0 == 448 && defined _HAVE_UINT64_T 927 | typedef uint64_t uintptr_t; 928 | typedef int64_t intptr_t; 929 | #else /* matches typical system types ILP32 and LP64 - but not IP16 or LLP64 */ 930 | typedef unsigned long uintptr_t; 931 | typedef long intptr_t; 932 | #endif 933 | #endif 934 | #endif 935 | 936 | /* shortcircuit*/ 937 | #endif 938 | /* once */ 939 | #endif 940 | #endif 941 | STDINT_EOF 942 | if cmp -s $ac_stdint_h $ac_stdint 2>/dev/null; then 943 | AC_MSG_NOTICE([$ac_stdint_h is unchanged]) 944 | else 945 | ac_dir=`AS_DIRNAME(["$ac_stdint_h"])` 946 | AS_MKDIR_P(["$ac_dir"]) 947 | rm -f $ac_stdint_h 948 | mv $ac_stdint $ac_stdint_h 949 | fi 950 | ],[# variables for create stdint.h replacement 951 | PACKAGE="$PACKAGE" 952 | VERSION="$VERSION" 953 | ac_stdint_h="$ac_stdint_h" 954 | _ac_stdint_h=AS_TR_CPP(_$PACKAGE-$ac_stdint_h) 955 | ac_cv_stdint_message="$ac_cv_stdint_message" 956 | ac_cv_header_stdint_t="$ac_cv_header_stdint_t" 957 | ac_cv_header_stdint_x="$ac_cv_header_stdint_x" 958 | ac_cv_header_stdint_o="$ac_cv_header_stdint_o" 959 | ac_cv_header_stdint_u="$ac_cv_header_stdint_u" 960 | ac_cv_type_uint64_t="$ac_cv_type_uint64_t" 961 | ac_cv_type_u_int64_t="$ac_cv_type_u_int64_t" 962 | ac_cv_stdint_char_model="$ac_cv_stdint_char_model" 963 | ac_cv_stdint_long_model="$ac_cv_stdint_long_model" 964 | ac_cv_type_int_least32_t="$ac_cv_type_int_least32_t" 965 | ac_cv_type_int_fast32_t="$ac_cv_type_int_fast32_t" 966 | ac_cv_type_intmax_t="$ac_cv_type_intmax_t" 967 | ]) 968 | ]) 969 | -------------------------------------------------------------------------------- /argp-ba.c: -------------------------------------------------------------------------------- 1 | /* Default definition for ARGP_PROGRAM_BUG_ADDRESS. 2 | Copyright (C) 1996-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | /* If set by the user program, it should point to string that is the 21 | bug-reporting address for the program. It will be printed by argp_help if 22 | the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help 23 | messages), embedded in a sentence that says something like `Report bugs to 24 | ADDR.'. */ 25 | const char *argp_program_bug_address; 26 | -------------------------------------------------------------------------------- /argp-eexst.c: -------------------------------------------------------------------------------- 1 | /* Default definition for ARGP_ERR_EXIT_STATUS 2 | Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | # include 22 | #endif 23 | 24 | #include 25 | 26 | #include "argp.h" 27 | 28 | /* The exit status that argp will use when exiting due to a parsing error. 29 | If not defined or set by the user program, this defaults to EX_USAGE from 30 | . */ 31 | error_t argp_err_exit_status = EX_USAGE; 32 | -------------------------------------------------------------------------------- /argp-fmtstream.c: -------------------------------------------------------------------------------- 1 | /* Word-wrapping and line-truncating streams 2 | Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | /* This package emulates glibc `line_wrap_stream' semantics for systems that 21 | don't have that. */ 22 | 23 | #ifdef HAVE_CONFIG_H 24 | # include 25 | #endif 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include "argp-namefrob.h" 35 | 36 | #ifndef ARGP_FMTSTREAM_USE_LINEWRAP 37 | 38 | #ifndef isblank 39 | #define isblank(ch) ((ch)==' ' || (ch)=='\t') 40 | #endif 41 | 42 | #if 0 43 | # include 44 | # include 45 | #endif 46 | 47 | #define INIT_BUF_SIZE 200 48 | #define PRINTF_SIZE_GUESS 150 49 | 50 | /* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines 51 | written on it with LMARGIN spaces and limits them to RMARGIN columns 52 | total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by 53 | replacing the whitespace before them with a newline and WMARGIN spaces. 54 | Otherwise, chars beyond RMARGIN are simply dropped until a newline. 55 | Returns NULL if there was an error. */ 56 | argp_fmtstream_t 57 | __argp_make_fmtstream (FILE *stream, 58 | size_t lmargin, size_t rmargin, ssize_t wmargin) 59 | { 60 | argp_fmtstream_t fs; 61 | 62 | fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream)); 63 | if (fs != NULL) 64 | { 65 | fs->stream = stream; 66 | 67 | fs->lmargin = lmargin; 68 | fs->rmargin = rmargin; 69 | fs->wmargin = wmargin; 70 | fs->point_col = 0; 71 | fs->point_offs = 0; 72 | 73 | fs->buf = (char *) malloc (INIT_BUF_SIZE); 74 | if (! fs->buf) 75 | { 76 | free (fs); 77 | fs = 0; 78 | } 79 | else 80 | { 81 | fs->p = fs->buf; 82 | fs->end = fs->buf + INIT_BUF_SIZE; 83 | } 84 | } 85 | 86 | return fs; 87 | } 88 | #if 0 89 | /* Not exported. */ 90 | #ifdef weak_alias 91 | weak_alias (__argp_make_fmtstream, argp_make_fmtstream) 92 | #endif 93 | #endif 94 | 95 | /* Flush FS to its stream, and free it (but don't close the stream). */ 96 | void 97 | __argp_fmtstream_free (argp_fmtstream_t fs) 98 | { 99 | __argp_fmtstream_update (fs); 100 | if (fs->p > fs->buf) 101 | { 102 | #if 0 103 | __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); 104 | #else 105 | fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); 106 | #endif 107 | } 108 | free (fs->buf); 109 | free (fs); 110 | } 111 | #if 0 112 | /* Not exported. */ 113 | #ifdef weak_alias 114 | weak_alias (__argp_fmtstream_free, argp_fmtstream_free) 115 | #endif 116 | #endif 117 | 118 | /* Process FS's buffer so that line wrapping is done from POINT_OFFS to the 119 | end of its buffer. This code is mostly from glibc stdio/linewrap.c. */ 120 | void 121 | __argp_fmtstream_update (argp_fmtstream_t fs) 122 | { 123 | char *buf, *nl; 124 | size_t len; 125 | 126 | /* Scan the buffer for newlines. */ 127 | buf = fs->buf + fs->point_offs; 128 | while (buf < fs->p) 129 | { 130 | size_t r; 131 | 132 | if (fs->point_col == 0 && fs->lmargin != 0) 133 | { 134 | /* We are starting a new line. Print spaces to the left margin. */ 135 | const size_t pad = fs->lmargin; 136 | if (fs->p + pad < fs->end) 137 | { 138 | /* We can fit in them in the buffer by moving the 139 | buffer text up and filling in the beginning. */ 140 | memmove (buf + pad, buf, fs->p - buf); 141 | fs->p += pad; /* Compensate for bigger buffer. */ 142 | memset (buf, ' ', pad); /* Fill in the spaces. */ 143 | buf += pad; /* Don't bother searching them. */ 144 | } 145 | else 146 | { 147 | /* No buffer space for spaces. Must flush. */ 148 | size_t i; 149 | for (i = 0; i < pad; i++) 150 | { 151 | #if 0 152 | if (_IO_fwide (fs->stream, 0) > 0) 153 | putwc_unlocked (L' ', fs->stream); 154 | else 155 | #endif 156 | putc_unlocked (' ', fs->stream); 157 | } 158 | } 159 | fs->point_col = pad; 160 | } 161 | 162 | len = fs->p - buf; 163 | nl = memchr (buf, '\n', len); 164 | 165 | if (fs->point_col < 0) 166 | fs->point_col = 0; 167 | 168 | if (!nl) 169 | { 170 | /* The buffer ends in a partial line. */ 171 | 172 | if (fs->point_col + len < fs->rmargin) 173 | { 174 | /* The remaining buffer text is a partial line and fits 175 | within the maximum line width. Advance point for the 176 | characters to be written and stop scanning. */ 177 | fs->point_col += len; 178 | break; 179 | } 180 | else 181 | /* Set the end-of-line pointer for the code below to 182 | the end of the buffer. */ 183 | nl = fs->p; 184 | } 185 | else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin) 186 | { 187 | /* The buffer contains a full line that fits within the maximum 188 | line width. Reset point and scan the next line. */ 189 | fs->point_col = 0; 190 | buf = nl + 1; 191 | continue; 192 | } 193 | 194 | /* This line is too long. */ 195 | r = fs->rmargin - 1; 196 | 197 | if (fs->wmargin < 0) 198 | { 199 | /* Truncate the line by overwriting the excess with the 200 | newline and anything after it in the buffer. */ 201 | if (nl < fs->p) 202 | { 203 | memmove (buf + (r - fs->point_col), nl, fs->p - nl); 204 | fs->p -= buf + (r - fs->point_col) - nl; 205 | /* Reset point for the next line and start scanning it. */ 206 | fs->point_col = 0; 207 | buf += r + 1; /* Skip full line plus \n. */ 208 | } 209 | else 210 | { 211 | /* The buffer ends with a partial line that is beyond the 212 | maximum line width. Advance point for the characters 213 | written, and discard those past the max from the buffer. */ 214 | fs->point_col += len; 215 | fs->p -= fs->point_col - r; 216 | break; 217 | } 218 | } 219 | else 220 | { 221 | /* Do word wrap. Go to the column just past the maximum line 222 | width and scan back for the beginning of the word there. 223 | Then insert a line break. */ 224 | 225 | char *p, *nextline; 226 | int i; 227 | 228 | p = buf + (r + 1 - fs->point_col); 229 | while (p >= buf && !isblank (*p)) 230 | --p; 231 | nextline = p + 1; /* This will begin the next line. */ 232 | 233 | if (nextline > buf) 234 | { 235 | /* Swallow separating blanks. */ 236 | if (p >= buf) 237 | do 238 | --p; 239 | while (p >= buf && isblank (*p)); 240 | nl = p + 1; /* The newline will replace the first blank. */ 241 | } 242 | else 243 | { 244 | /* A single word that is greater than the maximum line width. 245 | Oh well. Put it on an overlong line by itself. */ 246 | p = buf + (r + 1 - fs->point_col); 247 | /* Find the end of the long word. */ 248 | do 249 | ++p; 250 | while (p < nl && !isblank (*p)); 251 | if (p == nl) 252 | { 253 | /* It already ends a line. No fussing required. */ 254 | fs->point_col = 0; 255 | buf = nl + 1; 256 | continue; 257 | } 258 | /* We will move the newline to replace the first blank. */ 259 | nl = p; 260 | /* Swallow separating blanks. */ 261 | do 262 | ++p; 263 | while (isblank (*p)); 264 | /* The next line will start here. */ 265 | nextline = p; 266 | } 267 | 268 | /* Note: There are a bunch of tests below for 269 | NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall 270 | at the end of the buffer, and NEXTLINE is in fact empty (and so 271 | we need not be careful to maintain its contents). */ 272 | 273 | if ((nextline == buf + len + 1 274 | ? fs->end - nl < fs->wmargin + 1 275 | : nextline - (nl + 1) < fs->wmargin) 276 | && fs->p > nextline) 277 | { 278 | /* The margin needs more blanks than we removed. */ 279 | if (fs->end - fs->p > fs->wmargin + 1) 280 | /* Make some space for them. */ 281 | { 282 | size_t mv = fs->p - nextline; 283 | memmove (nl + 1 + fs->wmargin, nextline, mv); 284 | nextline = nl + 1 + fs->wmargin; 285 | len = nextline + mv - buf; 286 | *nl++ = '\n'; 287 | } 288 | else 289 | /* Output the first line so we can use the space. */ 290 | { 291 | #if 0 292 | __fxprintf (fs->stream, "%.*s\n", 293 | (int) (nl - fs->buf), fs->buf); 294 | #else 295 | if (nl > fs->buf) 296 | fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream); 297 | putc_unlocked ('\n', fs->stream); 298 | #endif 299 | 300 | len += buf - fs->buf; 301 | nl = buf = fs->buf; 302 | } 303 | } 304 | else 305 | /* We can fit the newline and blanks in before 306 | the next word. */ 307 | *nl++ = '\n'; 308 | 309 | if (nextline - nl >= fs->wmargin 310 | || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin)) 311 | /* Add blanks up to the wrap margin column. */ 312 | for (i = 0; i < fs->wmargin; ++i) 313 | *nl++ = ' '; 314 | else 315 | for (i = 0; i < fs->wmargin; ++i) 316 | #if 0 317 | if (_IO_fwide (fs->stream, 0) > 0) 318 | putwc_unlocked (L' ', fs->stream); 319 | else 320 | #endif 321 | putc_unlocked (' ', fs->stream); 322 | 323 | /* Copy the tail of the original buffer into the current buffer 324 | position. */ 325 | if (nl < nextline) 326 | memmove (nl, nextline, buf + len - nextline); 327 | len -= nextline - buf; 328 | 329 | /* Continue the scan on the remaining lines in the buffer. */ 330 | buf = nl; 331 | 332 | /* Restore bufp to include all the remaining text. */ 333 | fs->p = nl + len; 334 | 335 | /* Reset the counter of what has been output this line. If wmargin 336 | is 0, we want to avoid the lmargin getting added, so we set 337 | point_col to a magic value of -1 in that case. */ 338 | fs->point_col = fs->wmargin ? fs->wmargin : -1; 339 | } 340 | } 341 | 342 | /* Remember that we've scanned as far as the end of the buffer. */ 343 | fs->point_offs = fs->p - fs->buf; 344 | } 345 | 346 | /* Ensure that FS has space for AMOUNT more bytes in its buffer, either by 347 | growing the buffer, or by flushing it. True is returned iff we succeed. */ 348 | int 349 | __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount) 350 | { 351 | if ((size_t) (fs->end - fs->p) < amount) 352 | { 353 | ssize_t wrote; 354 | 355 | /* Flush FS's buffer. */ 356 | __argp_fmtstream_update (fs); 357 | 358 | #if 0 359 | __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf); 360 | wrote = fs->p - fs->buf; 361 | #else 362 | wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream); 363 | #endif 364 | if (wrote == fs->p - fs->buf) 365 | { 366 | fs->p = fs->buf; 367 | fs->point_offs = 0; 368 | } 369 | else 370 | { 371 | fs->p -= wrote; 372 | fs->point_offs -= wrote; 373 | memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf); 374 | return 0; 375 | } 376 | 377 | if ((size_t) (fs->end - fs->buf) < amount) 378 | /* Gotta grow the buffer. */ 379 | { 380 | size_t old_size = fs->end - fs->buf; 381 | size_t new_size = old_size + amount; 382 | char *new_buf; 383 | 384 | if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size))) 385 | { 386 | __set_errno (ENOMEM); 387 | return 0; 388 | } 389 | 390 | fs->buf = new_buf; 391 | fs->end = new_buf + new_size; 392 | fs->p = fs->buf; 393 | } 394 | } 395 | 396 | return 1; 397 | } 398 | 399 | ssize_t 400 | __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) 401 | { 402 | int out; 403 | size_t avail; 404 | size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */ 405 | 406 | do 407 | { 408 | va_list args; 409 | 410 | if (! __argp_fmtstream_ensure (fs, size_guess)) 411 | return -1; 412 | 413 | va_start (args, fmt); 414 | avail = fs->end - fs->p; 415 | out = vsnprintf (fs->p, avail, fmt, args); 416 | va_end (args); 417 | if ((size_t) out >= avail) 418 | size_guess = out + 1; 419 | } 420 | while ((size_t) out >= avail); 421 | 422 | fs->p += out; 423 | 424 | return out; 425 | } 426 | #if 0 427 | /* Not exported. */ 428 | #ifdef weak_alias 429 | weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf) 430 | #endif 431 | #endif 432 | 433 | #endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */ 434 | -------------------------------------------------------------------------------- /argp-fmtstream.h: -------------------------------------------------------------------------------- 1 | /* Word-wrapping and line-truncating streams. 2 | Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | /* This package emulates glibc `line_wrap_stream' semantics for systems that 21 | don't have that. If the system does have it, it is just a wrapper for 22 | that. This header file is only used internally while compiling argp, and 23 | shouldn't be installed. */ 24 | 25 | #ifndef _ARGP_FMTSTREAM_H 26 | #define _ARGP_FMTSTREAM_H 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #ifndef PRINTF_STYLE 33 | # if __GNUC__ >= 2 34 | # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) 35 | # else 36 | # define PRINTF_STYLE(f, a) 37 | # endif 38 | #endif 39 | 40 | #if 0 41 | /* line_wrap_stream is available, so use that. */ 42 | #define ARGP_FMTSTREAM_USE_LINEWRAP 43 | #endif 44 | 45 | #ifdef ARGP_FMTSTREAM_USE_LINEWRAP 46 | /* Just be a simple wrapper for line_wrap_stream; the semantics are 47 | *slightly* different, as line_wrap_stream doesn't actually make a new 48 | object, it just modifies the given stream (reversibly) to do 49 | line-wrapping. Since we control who uses this code, it doesn't matter. */ 50 | 51 | #include 52 | 53 | typedef FILE *argp_fmtstream_t; 54 | 55 | #define argp_make_fmtstream line_wrap_stream 56 | #define __argp_make_fmtstream line_wrap_stream 57 | #define argp_fmtstream_free line_unwrap_stream 58 | #define __argp_fmtstream_free line_unwrap_stream 59 | 60 | #define __argp_fmtstream_putc(fs,ch) putc(ch,fs) 61 | #define argp_fmtstream_putc(fs,ch) putc(ch,fs) 62 | #define __argp_fmtstream_puts(fs,str) fputs(str,fs) 63 | #define argp_fmtstream_puts(fs,str) fputs(str,fs) 64 | #define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) 65 | #define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs) 66 | #define __argp_fmtstream_printf fprintf 67 | #define argp_fmtstream_printf fprintf 68 | 69 | #define __argp_fmtstream_lmargin line_wrap_lmargin 70 | #define argp_fmtstream_lmargin line_wrap_lmargin 71 | #define __argp_fmtstream_set_lmargin line_wrap_set_lmargin 72 | #define argp_fmtstream_set_lmargin line_wrap_set_lmargin 73 | #define __argp_fmtstream_rmargin line_wrap_rmargin 74 | #define argp_fmtstream_rmargin line_wrap_rmargin 75 | #define __argp_fmtstream_set_rmargin line_wrap_set_rmargin 76 | #define argp_fmtstream_set_rmargin line_wrap_set_rmargin 77 | #define __argp_fmtstream_wmargin line_wrap_wmargin 78 | #define argp_fmtstream_wmargin line_wrap_wmargin 79 | #define __argp_fmtstream_set_wmargin line_wrap_set_wmargin 80 | #define argp_fmtstream_set_wmargin line_wrap_set_wmargin 81 | #define __argp_fmtstream_point line_wrap_point 82 | #define argp_fmtstream_point line_wrap_point 83 | 84 | #else /* !ARGP_FMTSTREAM_USE_LINEWRAP */ 85 | /* Guess we have to define our own version. */ 86 | 87 | 88 | struct argp_fmtstream 89 | { 90 | FILE *stream; /* The stream we're outputting to. */ 91 | 92 | size_t lmargin, rmargin; /* Left and right margins. */ 93 | ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */ 94 | 95 | /* Point in buffer to which we've processed for wrapping, but not output. */ 96 | size_t point_offs; 97 | /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */ 98 | ssize_t point_col; 99 | 100 | char *buf; /* Output buffer. */ 101 | char *p; /* Current end of text in BUF. */ 102 | char *end; /* Absolute end of BUF. */ 103 | }; 104 | 105 | typedef struct argp_fmtstream *argp_fmtstream_t; 106 | 107 | /* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines 108 | written on it with LMARGIN spaces and limits them to RMARGIN columns 109 | total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by 110 | replacing the whitespace before them with a newline and WMARGIN spaces. 111 | Otherwise, chars beyond RMARGIN are simply dropped until a newline. 112 | Returns NULL if there was an error. */ 113 | extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream, 114 | size_t __lmargin, 115 | size_t __rmargin, 116 | ssize_t __wmargin); 117 | extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream, 118 | size_t __lmargin, 119 | size_t __rmargin, 120 | ssize_t __wmargin); 121 | 122 | /* Flush __FS to its stream, and free it (but don't close the stream). */ 123 | extern void __argp_fmtstream_free (argp_fmtstream_t __fs); 124 | extern void argp_fmtstream_free (argp_fmtstream_t __fs); 125 | 126 | extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs, 127 | const char *__fmt, ...) 128 | PRINTF_STYLE(2,3); 129 | extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs, 130 | const char *__fmt, ...) 131 | PRINTF_STYLE(2,3); 132 | 133 | 134 | /* Access macros for various bits of state. */ 135 | #define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin) 136 | #define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin) 137 | #define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin) 138 | #define __argp_fmtstream_lmargin argp_fmtstream_lmargin 139 | #define __argp_fmtstream_rmargin argp_fmtstream_rmargin 140 | #define __argp_fmtstream_wmargin argp_fmtstream_wmargin 141 | 142 | /* Internal routines. */ 143 | extern void _argp_fmtstream_update (argp_fmtstream_t __fs); 144 | extern void __argp_fmtstream_update (argp_fmtstream_t __fs); 145 | extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); 146 | extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount); 147 | 148 | #if 1 149 | /* Inline versions of above routines. */ 150 | 151 | #if 1 152 | #define __argp_fmtstream_putc argp_fmtstream_putc 153 | #define __argp_fmtstream_puts argp_fmtstream_puts 154 | #define __argp_fmtstream_write argp_fmtstream_write 155 | #define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin 156 | #define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin 157 | #define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin 158 | #define __argp_fmtstream_point argp_fmtstream_point 159 | #define __argp_fmtstream_update _argp_fmtstream_update 160 | #define __argp_fmtstream_ensure _argp_fmtstream_ensure 161 | #endif 162 | 163 | #ifndef ARGP_FS_EI 164 | #define ARGP_FS_EI static inline 165 | #endif 166 | 167 | ARGP_FS_EI size_t 168 | __argp_fmtstream_write (argp_fmtstream_t __fs, const char *__str, size_t __len) 169 | { 170 | if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len)) 171 | { 172 | memcpy (__fs->p, __str, __len); 173 | __fs->p += __len; 174 | return __len; 175 | } 176 | else 177 | return 0; 178 | } 179 | 180 | ARGP_FS_EI int 181 | __argp_fmtstream_puts (argp_fmtstream_t __fs, const char *__str) 182 | { 183 | size_t __len = strlen (__str); 184 | if (__len) 185 | { 186 | size_t __wrote = __argp_fmtstream_write (__fs, __str, __len); 187 | return __wrote == __len ? 0 : -1; 188 | } 189 | else 190 | return 0; 191 | } 192 | 193 | ARGP_FS_EI int 194 | __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch) 195 | { 196 | if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1)) 197 | return *__fs->p++ = __ch; 198 | else 199 | return EOF; 200 | } 201 | 202 | /* Set __FS's left margin to __LMARGIN and return the old value. */ 203 | ARGP_FS_EI size_t 204 | __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin) 205 | { 206 | size_t __old; 207 | if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) 208 | __argp_fmtstream_update (__fs); 209 | __old = __fs->lmargin; 210 | __fs->lmargin = __lmargin; 211 | return __old; 212 | } 213 | 214 | /* Set __FS's right margin to __RMARGIN and return the old value. */ 215 | ARGP_FS_EI size_t 216 | __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin) 217 | { 218 | size_t __old; 219 | if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) 220 | __argp_fmtstream_update (__fs); 221 | __old = __fs->rmargin; 222 | __fs->rmargin = __rmargin; 223 | return __old; 224 | } 225 | 226 | /* Set FS's wrap margin to __WMARGIN and return the old value. */ 227 | ARGP_FS_EI size_t 228 | __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin) 229 | { 230 | size_t __old; 231 | if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) 232 | __argp_fmtstream_update (__fs); 233 | __old = __fs->wmargin; 234 | __fs->wmargin = __wmargin; 235 | return __old; 236 | } 237 | 238 | /* Return the column number of the current output point in __FS. */ 239 | ARGP_FS_EI size_t 240 | __argp_fmtstream_point (argp_fmtstream_t __fs) 241 | { 242 | if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs) 243 | __argp_fmtstream_update (__fs); 244 | return __fs->point_col >= 0 ? __fs->point_col : 0; 245 | } 246 | 247 | #if 1 248 | #undef __argp_fmtstream_putc 249 | #undef __argp_fmtstream_puts 250 | #undef __argp_fmtstream_write 251 | #undef __argp_fmtstream_set_lmargin 252 | #undef __argp_fmtstream_set_rmargin 253 | #undef __argp_fmtstream_set_wmargin 254 | #undef __argp_fmtstream_point 255 | #undef __argp_fmtstream_update 256 | #undef __argp_fmtstream_ensure 257 | #endif 258 | 259 | #endif /* __OPTIMIZE__ */ 260 | 261 | #endif /* ARGP_FMTSTREAM_USE_LINEWRAP */ 262 | 263 | #endif /* argp-fmtstream.h */ 264 | -------------------------------------------------------------------------------- /argp-namefrob.h: -------------------------------------------------------------------------------- 1 | /* Name frobnication for compiling argp outside of glibc 2 | Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | #if 1 21 | /* This code is written for inclusion in gnu-libc, and uses names in the 22 | namespace reserved for libc. If we're not compiling in libc, define those 23 | names to be the normal ones instead. */ 24 | 25 | /* argp-parse functions */ 26 | #undef __argp_parse 27 | #define __argp_parse argp_parse 28 | #undef __option_is_end 29 | #define __option_is_end _option_is_end 30 | #undef __option_is_short 31 | #define __option_is_short _option_is_short 32 | #undef __argp_input 33 | #define __argp_input _argp_input 34 | 35 | /* argp-help functions */ 36 | #undef __argp_help 37 | #define __argp_help argp_help 38 | #undef __argp_error 39 | #define __argp_error argp_error 40 | #undef __argp_failure 41 | #define __argp_failure argp_failure 42 | #undef __argp_state_help 43 | #define __argp_state_help argp_state_help 44 | #undef __argp_usage 45 | #define __argp_usage argp_usage 46 | 47 | /* argp-fmtstream functions */ 48 | #undef __argp_make_fmtstream 49 | #define __argp_make_fmtstream argp_make_fmtstream 50 | #undef __argp_fmtstream_free 51 | #define __argp_fmtstream_free argp_fmtstream_free 52 | #undef __argp_fmtstream_putc 53 | #define __argp_fmtstream_putc argp_fmtstream_putc 54 | #undef __argp_fmtstream_puts 55 | #define __argp_fmtstream_puts argp_fmtstream_puts 56 | #undef __argp_fmtstream_write 57 | #define __argp_fmtstream_write argp_fmtstream_write 58 | #undef __argp_fmtstream_printf 59 | #define __argp_fmtstream_printf argp_fmtstream_printf 60 | #undef __argp_fmtstream_set_lmargin 61 | #define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin 62 | #undef __argp_fmtstream_set_rmargin 63 | #define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin 64 | #undef __argp_fmtstream_set_wmargin 65 | #define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin 66 | #undef __argp_fmtstream_point 67 | #define __argp_fmtstream_point argp_fmtstream_point 68 | #undef __argp_fmtstream_update 69 | #define __argp_fmtstream_update _argp_fmtstream_update 70 | #undef __argp_fmtstream_ensure 71 | #define __argp_fmtstream_ensure _argp_fmtstream_ensure 72 | #undef __argp_fmtstream_lmargin 73 | #define __argp_fmtstream_lmargin argp_fmtstream_lmargin 74 | #undef __argp_fmtstream_rmargin 75 | #define __argp_fmtstream_rmargin argp_fmtstream_rmargin 76 | #undef __argp_fmtstream_wmargin 77 | #define __argp_fmtstream_wmargin argp_fmtstream_wmargin 78 | 79 | /* normal libc functions we call */ 80 | #undef __flockfile 81 | #define __flockfile flockfile 82 | #undef __funlockfile 83 | #define __funlockfile funlockfile 84 | #undef __mempcpy 85 | #define __mempcpy mempcpy 86 | #undef __sleep 87 | #define __sleep sleep 88 | #undef __strcasecmp 89 | #define __strcasecmp strcasecmp 90 | #undef __strchrnul 91 | #define __strchrnul strchrnul 92 | #undef __strerror_r 93 | #define __strerror_r strerror_r 94 | #undef __strndup 95 | #define __strndup strndup 96 | 97 | #if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED 98 | # define clearerr_unlocked(x) clearerr (x) 99 | #endif 100 | #if defined(HAVE_DECL_FEOF_UNLOCKED) && !HAVE_DECL_FEOF_UNLOCKED 101 | # define feof_unlocked(x) feof (x) 102 | # endif 103 | #if defined(HAVE_DECL_FERROR_UNLOCKED) && !HAVE_DECL_FERROR_UNLOCKED 104 | # define ferror_unlocked(x) ferror (x) 105 | # endif 106 | #if defined(HAVE_DECL_FFLUSH_UNLOCKED) && !HAVE_DECL_FFLUSH_UNLOCKED 107 | # define fflush_unlocked(x) fflush (x) 108 | # endif 109 | #if defined(HAVE_DECL_FGETS_UNLOCKED) && !HAVE_DECL_FGETS_UNLOCKED 110 | # define fgets_unlocked(x,y,z) fgets (x,y,z) 111 | # endif 112 | #if defined(HAVE_DECL_FPUTC_UNLOCKED) && !HAVE_DECL_FPUTC_UNLOCKED 113 | # define fputc_unlocked(x,y) fputc (x,y) 114 | # endif 115 | #if defined(HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED 116 | # define fputs_unlocked(x,y) fputs (x,y) 117 | # endif 118 | #if defined(HAVE_DECL_FREAD_UNLOCKED) && !HAVE_DECL_FREAD_UNLOCKED 119 | # define fread_unlocked(w,x,y,z) fread (w,x,y,z) 120 | # endif 121 | #if defined(HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED 122 | # define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) 123 | # endif 124 | #if defined(HAVE_DECL_GETC_UNLOCKED) && !HAVE_DECL_GETC_UNLOCKED 125 | # define getc_unlocked(x) getc (x) 126 | # endif 127 | #if defined(HAVE_DECL_GETCHAR_UNLOCKED) && !HAVE_DECL_GETCHAR_UNLOCKED 128 | # define getchar_unlocked() getchar () 129 | # endif 130 | #if defined(HAVE_DECL_PUTC_UNLOCKED) && !HAVE_DECL_PUTC_UNLOCKED 131 | # define putc_unlocked(x,y) putc (x,y) 132 | # endif 133 | #if defined(HAVE_DECL_PUTCHAR_UNLOCKED) && !HAVE_DECL_PUTCHAR_UNLOCKED 134 | # define putchar_unlocked(x) putchar (x) 135 | # endif 136 | 137 | extern char *__argp_basename (char *name); 138 | 139 | #endif /* !_LIBC */ 140 | 141 | #ifndef __set_errno 142 | #define __set_errno(e) (errno = (e)) 143 | #endif 144 | 145 | #if 0 || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 146 | # define __argp_short_program_name() (program_invocation_short_name) 147 | #else 148 | extern char *__argp_short_program_name (void); 149 | #endif 150 | -------------------------------------------------------------------------------- /argp-parse.c: -------------------------------------------------------------------------------- 1 | /* Hierarchial argument parsing, layered over getopt 2 | Copyright (C) 1995-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include 22 | #endif 23 | 24 | /* AIX requires this to be the first thing in the file. */ 25 | #ifndef __GNUC__ 26 | # if HAVE_ALLOCA_H || 0 27 | # include 28 | # else 29 | # ifdef _AIX 30 | #pragma alloca 31 | # else 32 | # ifndef alloca /* predefined by HP cc +Olibcalls */ 33 | char *alloca (); 34 | # endif 35 | # endif 36 | # endif 37 | #endif 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #ifndef _ 46 | /* This is for other GNU distributions with internationalized messages. 47 | When compiling libc, the _ macro is predefined. */ 48 | # if defined HAVE_LIBINTL_H || 0 49 | # include 50 | # if 0 51 | # undef dgettext 52 | # define dgettext(domain, msgid) \ 53 | __dcgettext (domain, msgid, LC_MESSAGES) 54 | # endif 55 | # else 56 | # define dgettext(domain, msgid) (msgid) 57 | # define gettext(msgid) (msgid) 58 | # endif 59 | #endif 60 | #ifndef N_ 61 | # define N_(msgid) (msgid) 62 | #endif 63 | 64 | #include 65 | #include "argp-namefrob.h" 66 | 67 | /* Getopt return values. */ 68 | #define KEY_END (-1) /* The end of the options. */ 69 | #define KEY_ARG 1 /* A non-option argument. */ 70 | #define KEY_ERR '?' /* An error parsing the options. */ 71 | 72 | /* The meta-argument used to prevent any further arguments being interpreted 73 | as options. */ 74 | #define QUOTE "--" 75 | 76 | /* The number of bits we steal in a long-option value for our own use. */ 77 | #define GROUP_BITS CHAR_BIT 78 | 79 | /* The number of bits available for the user value. */ 80 | #define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS) 81 | #define USER_MASK ((1 << USER_BITS) - 1) 82 | 83 | /* EZ alias for ARGP_ERR_UNKNOWN. */ 84 | #define EBADKEY ARGP_ERR_UNKNOWN 85 | 86 | /* Default options. */ 87 | 88 | /* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep 89 | for one second intervals, decrementing _ARGP_HANG until it's zero. Thus 90 | you can force the program to continue by attaching a debugger and setting 91 | it to 0 yourself. */ 92 | static volatile int _argp_hang; 93 | 94 | #define OPT_PROGNAME -2 95 | #define OPT_USAGE -3 96 | #define OPT_HANG -4 97 | 98 | static const struct argp_option argp_default_options[] = 99 | { 100 | {"help", '?', 0, 0, N_("Give this help list"), -1}, 101 | {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")}, 102 | {"program-name",OPT_PROGNAME, N_("NAME"), OPTION_HIDDEN, 103 | N_("Set the program name")}, 104 | {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, 105 | N_("Hang for SECS seconds (default 3600)")}, 106 | {0, 0} 107 | }; 108 | 109 | static error_t 110 | argp_default_parser (int key, char *arg, struct argp_state *state) 111 | { 112 | switch (key) 113 | { 114 | case '?': 115 | __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP); 116 | break; 117 | case OPT_USAGE: 118 | __argp_state_help (state, state->out_stream, 119 | ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); 120 | break; 121 | 122 | case OPT_PROGNAME: /* Set the program name. */ 123 | #if 0 || HAVE_DECL_PROGRAM_INVOCATION_NAME 124 | program_invocation_name = arg; 125 | #endif 126 | /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka 127 | __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined 128 | to be that, so we have to be a bit careful here.] */ 129 | 130 | /* Update what we use for messages. */ 131 | state->name = strrchr (arg, '/'); 132 | if (state->name) 133 | state->name++; 134 | else 135 | state->name = arg; 136 | 137 | #if 0 || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 138 | program_invocation_short_name = state->name; 139 | #endif 140 | 141 | if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) 142 | == ARGP_PARSE_ARGV0) 143 | /* Update what getopt uses too. */ 144 | state->argv[0] = arg; 145 | 146 | break; 147 | 148 | case OPT_HANG: 149 | _argp_hang = atoi (arg ? arg : "3600"); 150 | while (_argp_hang-- > 0) 151 | __sleep (1); 152 | break; 153 | 154 | default: 155 | return EBADKEY; 156 | } 157 | return 0; 158 | } 159 | 160 | static const struct argp argp_default_argp = 161 | {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"}; 162 | 163 | 164 | static const struct argp_option argp_version_options[] = 165 | { 166 | {"version", 'V', 0, 0, N_("Print program version"), -1}, 167 | {0, 0} 168 | }; 169 | 170 | static error_t 171 | argp_version_parser (int key, char *arg, struct argp_state *state) 172 | { 173 | switch (key) 174 | { 175 | case 'V': 176 | if (argp_program_version_hook) 177 | (*argp_program_version_hook) (state->out_stream, state); 178 | else if (argp_program_version) 179 | fprintf (state->out_stream, "%s\n", argp_program_version); 180 | else 181 | __argp_error (state, dgettext (state->root_argp->argp_domain, 182 | "(PROGRAM ERROR) No version known!?")); 183 | if (! (state->flags & ARGP_NO_EXIT)) 184 | exit (0); 185 | break; 186 | default: 187 | return EBADKEY; 188 | } 189 | return 0; 190 | } 191 | 192 | static const struct argp argp_version_argp = 193 | {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"}; 194 | 195 | /* Returns the offset into the getopt long options array LONG_OPTIONS of a 196 | long option with called NAME, or -1 if none is found. Passing NULL as 197 | NAME will return the number of options. */ 198 | static int 199 | find_long_option (struct option *long_options, const char *name) 200 | { 201 | struct option *l = long_options; 202 | while (l->name != NULL) 203 | if (name != NULL && strcmp (l->name, name) == 0) 204 | return l - long_options; 205 | else 206 | l++; 207 | if (name == NULL) 208 | return l - long_options; 209 | else 210 | return -1; 211 | } 212 | 213 | 214 | /* The state of a `group' during parsing. Each group corresponds to a 215 | particular argp structure from the tree of such descending from the top 216 | level argp passed to argp_parse. */ 217 | struct group 218 | { 219 | /* This group's parsing function. */ 220 | argp_parser_t parser; 221 | 222 | /* Which argp this group is from. */ 223 | const struct argp *argp; 224 | 225 | /* Points to the point in SHORT_OPTS corresponding to the end of the short 226 | options for this group. We use it to determine from which group a 227 | particular short options is from. */ 228 | char *short_end; 229 | 230 | /* The number of non-option args sucessfully handled by this parser. */ 231 | unsigned args_processed; 232 | 233 | /* This group's parser's parent's group. */ 234 | struct group *parent; 235 | unsigned parent_index; /* And the our position in the parent. */ 236 | 237 | /* These fields are swapped into and out of the state structure when 238 | calling this group's parser. */ 239 | void *input, **child_inputs; 240 | void *hook; 241 | }; 242 | 243 | /* Call GROUP's parser with KEY and ARG, swapping any group-specific info 244 | from STATE before calling, and back into state afterwards. If GROUP has 245 | no parser, EBADKEY is returned. */ 246 | static error_t 247 | group_parse (struct group *group, struct argp_state *state, int key, char *arg) 248 | { 249 | if (group->parser) 250 | { 251 | error_t err; 252 | state->hook = group->hook; 253 | state->input = group->input; 254 | state->child_inputs = group->child_inputs; 255 | state->arg_num = group->args_processed; 256 | err = (*group->parser)(key, arg, state); 257 | group->hook = state->hook; 258 | return err; 259 | } 260 | else 261 | return EBADKEY; 262 | } 263 | 264 | struct parser 265 | { 266 | const struct argp *argp; 267 | 268 | /* SHORT_OPTS is the getopt short options string for the union of all the 269 | groups of options. */ 270 | char *short_opts; 271 | /* LONG_OPTS is the array of getop long option structures for the union of 272 | all the groups of options. */ 273 | struct option *long_opts; 274 | 275 | /* States of the various parsing groups. */ 276 | struct group *groups; 277 | /* The end of the GROUPS array. */ 278 | struct group *egroup; 279 | /* An vector containing storage for the CHILD_INPUTS field in all groups. */ 280 | void **child_inputs; 281 | 282 | /* True if we think using getopt is still useful; if false, then 283 | remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is 284 | cleared whenever getopt returns KEY_END, but may be set again if the user 285 | moves the next argument pointer backwards. */ 286 | int try_getopt; 287 | 288 | /* State block supplied to parsing routines. */ 289 | struct argp_state state; 290 | 291 | /* Memory used by this parser. */ 292 | void *storage; 293 | }; 294 | 295 | /* The next usable entries in the various parser tables being filled in by 296 | convert_options. */ 297 | struct parser_convert_state 298 | { 299 | struct parser *parser; 300 | char *short_end; 301 | struct option *long_end; 302 | void **child_inputs_end; 303 | }; 304 | 305 | /* Converts all options in ARGP (which is put in GROUP) and ancestors 306 | into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and 307 | CVT->LONG_END are the points at which new options are added. Returns the 308 | next unused group entry. CVT holds state used during the conversion. */ 309 | static struct group * 310 | convert_options (const struct argp *argp, 311 | struct group *parent, unsigned parent_index, 312 | struct group *group, struct parser_convert_state *cvt) 313 | { 314 | /* REAL is the most recent non-alias value of OPT. */ 315 | const struct argp_option *real = argp->options; 316 | const struct argp_child *children = argp->children; 317 | 318 | if (real || argp->parser) 319 | { 320 | const struct argp_option *opt; 321 | 322 | if (real) 323 | for (opt = real; !__option_is_end (opt); opt++) 324 | { 325 | if (! (opt->flags & OPTION_ALIAS)) 326 | /* OPT isn't an alias, so we can use values from it. */ 327 | real = opt; 328 | 329 | if (! (real->flags & OPTION_DOC)) 330 | /* A real option (not just documentation). */ 331 | { 332 | if (__option_is_short (opt)) 333 | /* OPT can be used as a short option. */ 334 | { 335 | *cvt->short_end++ = opt->key; 336 | if (real->arg) 337 | { 338 | *cvt->short_end++ = ':'; 339 | if (real->flags & OPTION_ARG_OPTIONAL) 340 | *cvt->short_end++ = ':'; 341 | } 342 | *cvt->short_end = '\0'; /* keep 0 terminated */ 343 | } 344 | 345 | if (opt->name 346 | && find_long_option (cvt->parser->long_opts, opt->name) < 0) 347 | /* OPT can be used as a long option. */ 348 | { 349 | cvt->long_end->name = opt->name; 350 | cvt->long_end->has_arg = 351 | (real->arg 352 | ? (real->flags & OPTION_ARG_OPTIONAL 353 | ? optional_argument 354 | : required_argument) 355 | : no_argument); 356 | cvt->long_end->flag = 0; 357 | /* we add a disambiguating code to all the user's 358 | values (which is removed before we actually call 359 | the function to parse the value); this means that 360 | the user loses use of the high 8 bits in all his 361 | values (the sign of the lower bits is preserved 362 | however)... */ 363 | cvt->long_end->val = 364 | ((opt->key ? opt->key : real->key) & USER_MASK) 365 | + (((group - cvt->parser->groups) + 1) << USER_BITS); 366 | 367 | /* Keep the LONG_OPTS list terminated. */ 368 | (++cvt->long_end)->name = NULL; 369 | } 370 | } 371 | } 372 | 373 | group->parser = argp->parser; 374 | group->argp = argp; 375 | group->short_end = cvt->short_end; 376 | group->args_processed = 0; 377 | group->parent = parent; 378 | group->parent_index = parent_index; 379 | group->input = 0; 380 | group->hook = 0; 381 | group->child_inputs = 0; 382 | 383 | if (children) 384 | /* Assign GROUP's CHILD_INPUTS field some space from 385 | CVT->child_inputs_end.*/ 386 | { 387 | unsigned num_children = 0; 388 | while (children[num_children].argp) 389 | num_children++; 390 | group->child_inputs = cvt->child_inputs_end; 391 | cvt->child_inputs_end += num_children; 392 | } 393 | 394 | parent = group++; 395 | } 396 | else 397 | parent = 0; 398 | 399 | if (children) 400 | { 401 | unsigned index = 0; 402 | while (children->argp) 403 | group = 404 | convert_options (children++->argp, parent, index++, group, cvt); 405 | } 406 | 407 | return group; 408 | } 409 | 410 | /* Find the merged set of getopt options, with keys appropriately prefixed. */ 411 | static void 412 | parser_convert (struct parser *parser, const struct argp *argp, int flags) 413 | { 414 | struct parser_convert_state cvt; 415 | 416 | cvt.parser = parser; 417 | cvt.short_end = parser->short_opts; 418 | cvt.long_end = parser->long_opts; 419 | cvt.child_inputs_end = parser->child_inputs; 420 | 421 | if (flags & ARGP_IN_ORDER) 422 | *cvt.short_end++ = '-'; 423 | else if (flags & ARGP_NO_ARGS) 424 | *cvt.short_end++ = '+'; 425 | *cvt.short_end = '\0'; 426 | 427 | cvt.long_end->name = NULL; 428 | 429 | parser->argp = argp; 430 | 431 | if (argp) 432 | parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt); 433 | else 434 | parser->egroup = parser->groups; /* No parsers at all! */ 435 | } 436 | 437 | /* Lengths of various parser fields which we will allocated. */ 438 | struct parser_sizes 439 | { 440 | size_t short_len; /* Getopt short options string. */ 441 | size_t long_len; /* Getopt long options vector. */ 442 | size_t num_groups; /* Group structures we allocate. */ 443 | size_t num_child_inputs; /* Child input slots. */ 444 | }; 445 | 446 | /* For ARGP, increments the NUM_GROUPS field in SZS by the total number of 447 | argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by 448 | the maximum lengths of the resulting merged getopt short options string and 449 | long-options array, respectively. */ 450 | static void 451 | calc_sizes (const struct argp *argp, struct parser_sizes *szs) 452 | { 453 | const struct argp_child *child = argp->children; 454 | const struct argp_option *opt = argp->options; 455 | 456 | if (opt || argp->parser) 457 | { 458 | szs->num_groups++; 459 | if (opt) 460 | { 461 | int num_opts = 0; 462 | while (!__option_is_end (opt++)) 463 | num_opts++; 464 | szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ 465 | szs->long_len += num_opts; 466 | } 467 | } 468 | 469 | if (child) 470 | while (child->argp) 471 | { 472 | calc_sizes ((child++)->argp, szs); 473 | szs->num_child_inputs++; 474 | } 475 | } 476 | 477 | /* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ 478 | static error_t 479 | parser_init (struct parser *parser, const struct argp *argp, 480 | int argc, char **argv, int flags, void *input) 481 | { 482 | error_t err = 0; 483 | struct group *group; 484 | struct parser_sizes szs; 485 | 486 | szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1; 487 | szs.long_len = 0; 488 | szs.num_groups = 0; 489 | szs.num_child_inputs = 0; 490 | 491 | if (argp) 492 | calc_sizes (argp, &szs); 493 | 494 | /* Lengths of the various bits of storage used by PARSER. */ 495 | #define GLEN (szs.num_groups + 1) * sizeof (struct group) 496 | #define CLEN (szs.num_child_inputs * sizeof (void *)) 497 | #define LLEN ((szs.long_len + 1) * sizeof (struct option)) 498 | #define SLEN (szs.short_len + 1) 499 | 500 | parser->storage = malloc (GLEN + CLEN + LLEN + SLEN); 501 | if (! parser->storage) 502 | return ENOMEM; 503 | 504 | parser->groups = parser->storage; 505 | parser->child_inputs = parser->storage + GLEN; 506 | parser->long_opts = parser->storage + GLEN + CLEN; 507 | parser->short_opts = parser->storage + GLEN + CLEN + LLEN; 508 | 509 | memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *)); 510 | parser_convert (parser, argp, flags); 511 | 512 | memset (&parser->state, 0, sizeof (struct argp_state)); 513 | parser->state.root_argp = parser->argp; 514 | parser->state.argc = argc; 515 | parser->state.argv = argv; 516 | parser->state.flags = flags; 517 | parser->state.err_stream = stderr; 518 | parser->state.out_stream = stdout; 519 | parser->state.next = 0; /* Tell getopt to initialize. */ 520 | parser->state.pstate = parser; 521 | 522 | parser->try_getopt = 1; 523 | 524 | /* Call each parser for the first time, giving it a chance to propagate 525 | values to child parsers. */ 526 | if (parser->groups < parser->egroup) 527 | parser->groups->input = input; 528 | for (group = parser->groups; 529 | group < parser->egroup && (!err || err == EBADKEY); 530 | group++) 531 | { 532 | if (group->parent) 533 | /* If a child parser, get the initial input value from the parent. */ 534 | group->input = group->parent->child_inputs[group->parent_index]; 535 | 536 | if (!group->parser 537 | && group->argp->children && group->argp->children->argp) 538 | /* For the special case where no parsing function is supplied for an 539 | argp, propagate its input to its first child, if any (this just 540 | makes very simple wrapper argps more convenient). */ 541 | group->child_inputs[0] = group->input; 542 | 543 | err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); 544 | } 545 | if (err == EBADKEY) 546 | err = 0; /* Some parser didn't understand. */ 547 | 548 | if (err) 549 | return err; 550 | 551 | if (parser->state.flags & ARGP_NO_ERRS) 552 | { 553 | opterr = 0; 554 | if (parser->state.flags & ARGP_PARSE_ARGV0) 555 | /* getopt always skips ARGV[0], so we have to fake it out. As long 556 | as OPTERR is 0, then it shouldn't actually try to access it. */ 557 | parser->state.argv--, parser->state.argc++; 558 | } 559 | else 560 | opterr = 1; /* Print error messages. */ 561 | 562 | if (parser->state.argv == argv && argv[0]) 563 | /* There's an argv[0]; use it for messages. */ 564 | { 565 | char *short_name = strrchr (argv[0], '/'); 566 | parser->state.name = short_name ? short_name + 1 : argv[0]; 567 | } 568 | else 569 | parser->state.name = __argp_short_program_name (); 570 | 571 | return 0; 572 | } 573 | 574 | /* Free any storage consumed by PARSER (but not PARSER itself). */ 575 | static error_t 576 | parser_finalize (struct parser *parser, 577 | error_t err, int arg_ebadkey, int *end_index) 578 | { 579 | struct group *group; 580 | 581 | if (err == EBADKEY && arg_ebadkey) 582 | /* Suppress errors generated by unparsed arguments. */ 583 | err = 0; 584 | 585 | if (! err) 586 | { 587 | if (parser->state.next == parser->state.argc) 588 | /* We successfully parsed all arguments! Call all the parsers again, 589 | just a few more times... */ 590 | { 591 | for (group = parser->groups; 592 | group < parser->egroup && (!err || err==EBADKEY); 593 | group++) 594 | if (group->args_processed == 0) 595 | err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); 596 | for (group = parser->egroup - 1; 597 | group >= parser->groups && (!err || err==EBADKEY); 598 | group--) 599 | err = group_parse (group, &parser->state, ARGP_KEY_END, 0); 600 | 601 | if (err == EBADKEY) 602 | err = 0; /* Some parser didn't understand. */ 603 | 604 | /* Tell the user that all arguments are parsed. */ 605 | if (end_index) 606 | *end_index = parser->state.next; 607 | } 608 | else if (end_index) 609 | /* Return any remaining arguments to the user. */ 610 | *end_index = parser->state.next; 611 | else 612 | /* No way to return the remaining arguments, they must be bogus. */ 613 | { 614 | if (!(parser->state.flags & ARGP_NO_ERRS) 615 | && parser->state.err_stream) 616 | fprintf (parser->state.err_stream, 617 | dgettext (parser->argp->argp_domain, 618 | "%s: Too many arguments\n"), 619 | parser->state.name); 620 | err = EBADKEY; 621 | } 622 | } 623 | 624 | /* Okay, we're all done, with either an error or success; call the parsers 625 | to indicate which one. */ 626 | 627 | if (err) 628 | { 629 | /* Maybe print an error message. */ 630 | if (err == EBADKEY) 631 | /* An appropriate message describing what the error was should have 632 | been printed earlier. */ 633 | __argp_state_help (&parser->state, parser->state.err_stream, 634 | ARGP_HELP_STD_ERR); 635 | 636 | /* Since we didn't exit, give each parser an error indication. */ 637 | for (group = parser->groups; group < parser->egroup; group++) 638 | group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); 639 | } 640 | else 641 | /* Notify parsers of success, and propagate back values from parsers. */ 642 | { 643 | /* We pass over the groups in reverse order so that child groups are 644 | given a chance to do there processing before passing back a value to 645 | the parent. */ 646 | for (group = parser->egroup - 1 647 | ; group >= parser->groups && (!err || err == EBADKEY) 648 | ; group--) 649 | err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); 650 | if (err == EBADKEY) 651 | err = 0; /* Some parser didn't understand. */ 652 | } 653 | 654 | /* Call parsers once more, to do any final cleanup. Errors are ignored. */ 655 | for (group = parser->egroup - 1; group >= parser->groups; group--) 656 | group_parse (group, &parser->state, ARGP_KEY_FINI, 0); 657 | 658 | if (err == EBADKEY) 659 | err = EINVAL; 660 | 661 | free (parser->storage); 662 | 663 | return err; 664 | } 665 | 666 | /* Call the user parsers to parse the non-option argument VAL, at the current 667 | position, returning any error. The state NEXT pointer is assumed to have 668 | been adjusted (by getopt) to point after this argument; this function will 669 | adjust it correctly to reflect however many args actually end up being 670 | consumed. */ 671 | static error_t 672 | parser_parse_arg (struct parser *parser, char *val) 673 | { 674 | /* Save the starting value of NEXT, first adjusting it so that the arg 675 | we're parsing is again the front of the arg vector. */ 676 | int index = --parser->state.next; 677 | error_t err = EBADKEY; 678 | struct group *group; 679 | int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ 680 | 681 | /* Try to parse the argument in each parser. */ 682 | for (group = parser->groups 683 | ; group < parser->egroup && err == EBADKEY 684 | ; group++) 685 | { 686 | parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ 687 | key = ARGP_KEY_ARG; 688 | err = group_parse (group, &parser->state, key, val); 689 | 690 | if (err == EBADKEY) 691 | /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ 692 | { 693 | parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ 694 | key = ARGP_KEY_ARGS; 695 | err = group_parse (group, &parser->state, key, 0); 696 | } 697 | } 698 | 699 | if (! err) 700 | { 701 | if (key == ARGP_KEY_ARGS) 702 | /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't 703 | changed by the user, *all* arguments should be considered 704 | consumed. */ 705 | parser->state.next = parser->state.argc; 706 | 707 | if (parser->state.next > index) 708 | /* Remember that we successfully processed a non-option 709 | argument -- but only if the user hasn't gotten tricky and set 710 | the clock back. */ 711 | (--group)->args_processed += (parser->state.next - index); 712 | else 713 | /* The user wants to reparse some args, give getopt another try. */ 714 | parser->try_getopt = 1; 715 | } 716 | 717 | return err; 718 | } 719 | 720 | /* Call the user parsers to parse the option OPT, with argument VAL, at the 721 | current position, returning any error. */ 722 | static error_t 723 | parser_parse_opt (struct parser *parser, int opt, char *val) 724 | { 725 | /* The group key encoded in the high bits; 0 for short opts or 726 | group_number + 1 for long opts. */ 727 | int group_key = opt >> USER_BITS; 728 | error_t err = EBADKEY; 729 | 730 | if (group_key == 0) 731 | /* A short option. By comparing OPT's position in SHORT_OPTS to the 732 | various starting positions in each group's SHORT_END field, we can 733 | determine which group OPT came from. */ 734 | { 735 | struct group *group; 736 | char *short_index = strchr (parser->short_opts, opt); 737 | 738 | if (short_index) 739 | for (group = parser->groups; group < parser->egroup; group++) 740 | if (group->short_end > short_index) 741 | { 742 | err = group_parse (group, &parser->state, opt, optarg); 743 | break; 744 | } 745 | } 746 | else 747 | /* A long option. We use shifts instead of masking for extracting 748 | the user value in order to preserve the sign. */ 749 | err = 750 | group_parse (&parser->groups[group_key - 1], &parser->state, 751 | (opt << GROUP_BITS) >> GROUP_BITS, optarg); 752 | 753 | if (err == EBADKEY) 754 | /* At least currently, an option not recognized is an error in the 755 | parser, because we pre-compute which parser is supposed to deal 756 | with each option. */ 757 | { 758 | static const char bad_key_err[] = 759 | N_("(PROGRAM ERROR) Option should have been recognized!?"); 760 | if (group_key == 0) 761 | __argp_error (&parser->state, "-%c: %s", opt, 762 | dgettext (parser->argp->argp_domain, bad_key_err)); 763 | else 764 | { 765 | struct option *long_opt = parser->long_opts; 766 | while (long_opt->val != opt && long_opt->name) 767 | long_opt++; 768 | __argp_error (&parser->state, "--%s: %s", 769 | long_opt->name ? long_opt->name : "???", 770 | dgettext (parser->argp->argp_domain, bad_key_err)); 771 | } 772 | } 773 | 774 | return err; 775 | } 776 | 777 | /* Parse the next argument in PARSER (as indicated by PARSER->state.next). 778 | Any error from the parsers is returned, and *ARGP_EBADKEY indicates 779 | whether a value of EBADKEY is due to an unrecognized argument (which is 780 | generally not fatal). */ 781 | static error_t 782 | parser_parse_next (struct parser *parser, int *arg_ebadkey) 783 | { 784 | int opt; 785 | error_t err = 0; 786 | 787 | if (parser->state.quoted && parser->state.next < parser->state.quoted) 788 | /* The next argument pointer has been moved to before the quoted 789 | region, so pretend we never saw the quoting `--', and give getopt 790 | another chance. If the user hasn't removed it, getopt will just 791 | process it again. */ 792 | parser->state.quoted = 0; 793 | 794 | if (parser->try_getopt && !parser->state.quoted) 795 | /* Give getopt a chance to parse this. */ 796 | { 797 | /* Put it back in OPTIND for getopt. */ 798 | optind = parser->state.next; 799 | /* Distinguish KEY_ERR from a real option. */ 800 | optopt = KEY_END; 801 | if (parser->state.flags & ARGP_LONG_ONLY) 802 | opt = getopt_long_only (parser->state.argc, parser->state.argv, 803 | parser->short_opts, parser->long_opts, 0); 804 | else 805 | opt = getopt_long (parser->state.argc, parser->state.argv, 806 | parser->short_opts, parser->long_opts, 0); 807 | /* And see what getopt did. */ 808 | parser->state.next = optind; 809 | 810 | if (opt == KEY_END) 811 | /* Getopt says there are no more options, so stop using 812 | getopt; we'll continue if necessary on our own. */ 813 | { 814 | parser->try_getopt = 0; 815 | if (parser->state.next > 1 816 | && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) 817 | == 0) 818 | /* Not only is this the end of the options, but it's a 819 | `quoted' region, which may have args that *look* like 820 | options, so we definitely shouldn't try to use getopt past 821 | here, whatever happens. */ 822 | parser->state.quoted = parser->state.next; 823 | } 824 | else if (opt == KEY_ERR && optopt != KEY_END) 825 | /* KEY_ERR can have the same value as a valid user short 826 | option, but in the case of a real error, getopt sets OPTOPT 827 | to the offending character, which can never be KEY_END. */ 828 | { 829 | *arg_ebadkey = 0; 830 | return EBADKEY; 831 | } 832 | } 833 | else 834 | opt = KEY_END; 835 | 836 | if (opt == KEY_END) 837 | { 838 | /* We're past what getopt considers the options. */ 839 | if (parser->state.next >= parser->state.argc 840 | || (parser->state.flags & ARGP_NO_ARGS)) 841 | /* Indicate that we're done. */ 842 | { 843 | *arg_ebadkey = 1; 844 | return EBADKEY; 845 | } 846 | else 847 | /* A non-option arg; simulate what getopt might have done. */ 848 | { 849 | opt = KEY_ARG; 850 | optarg = parser->state.argv[parser->state.next++]; 851 | } 852 | } 853 | 854 | if (opt == KEY_ARG) 855 | /* A non-option argument; try each parser in turn. */ 856 | err = parser_parse_arg (parser, optarg); 857 | else 858 | err = parser_parse_opt (parser, opt, optarg); 859 | 860 | if (err == EBADKEY) 861 | *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG); 862 | 863 | return err; 864 | } 865 | 866 | /* Parse the options strings in ARGC & ARGV according to the argp in ARGP. 867 | FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the 868 | index in ARGV of the first unparsed option is returned in it. If an 869 | unknown option is present, EINVAL is returned; if some parser routine 870 | returned a non-zero value, it is returned; otherwise 0 is returned. */ 871 | error_t 872 | __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, 873 | int *end_index, void *input) 874 | { 875 | error_t err; 876 | struct parser parser; 877 | 878 | /* If true, then err == EBADKEY is a result of a non-option argument failing 879 | to be parsed (which in some cases isn't actually an error). */ 880 | int arg_ebadkey = 0; 881 | 882 | if (! (flags & ARGP_NO_HELP)) 883 | /* Add our own options. */ 884 | { 885 | struct argp_child *child = alloca (4 * sizeof (struct argp_child)); 886 | struct argp *top_argp = alloca (sizeof (struct argp)); 887 | 888 | /* TOP_ARGP has no options, it just serves to group the user & default 889 | argps. */ 890 | memset (top_argp, 0, sizeof (*top_argp)); 891 | top_argp->children = child; 892 | 893 | memset (child, 0, 4 * sizeof (struct argp_child)); 894 | 895 | if (argp) 896 | (child++)->argp = argp; 897 | (child++)->argp = &argp_default_argp; 898 | if (argp_program_version || argp_program_version_hook) 899 | (child++)->argp = &argp_version_argp; 900 | child->argp = 0; 901 | 902 | argp = top_argp; 903 | } 904 | 905 | /* Construct a parser for these arguments. */ 906 | err = parser_init (&parser, argp, argc, argv, flags, input); 907 | 908 | if (! err) 909 | /* Parse! */ 910 | { 911 | while (! err) 912 | err = parser_parse_next (&parser, &arg_ebadkey); 913 | err = parser_finalize (&parser, err, arg_ebadkey, end_index); 914 | } 915 | 916 | return err; 917 | } 918 | #ifdef weak_alias 919 | weak_alias (__argp_parse, argp_parse) 920 | #endif 921 | 922 | /* Return the input field for ARGP in the parser corresponding to STATE; used 923 | by the help routines. */ 924 | void * 925 | __argp_input (const struct argp *argp, const struct argp_state *state) 926 | { 927 | if (state) 928 | { 929 | struct group *group; 930 | struct parser *parser = state->pstate; 931 | 932 | for (group = parser->groups; group < parser->egroup; group++) 933 | if (group->argp == argp) 934 | return group->input; 935 | } 936 | 937 | return 0; 938 | } 939 | #ifdef weak_alias 940 | weak_alias (__argp_input, _argp_input) 941 | #endif 942 | -------------------------------------------------------------------------------- /argp-pv.c: -------------------------------------------------------------------------------- 1 | /* Default definition for ARGP_PROGRAM_VERSION. 2 | Copyright (C) 1996-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | /* If set by the user program to a non-zero value, then a default option 21 | --version is added (unless the ARGP_NO_HELP flag is used), which will 22 | print this this string followed by a newline and exit (unless the 23 | ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ 24 | const char *argp_program_version; 25 | -------------------------------------------------------------------------------- /argp-pvh.c: -------------------------------------------------------------------------------- 1 | /* Default definition for ARGP_PROGRAM_VERSION_HOOK. 2 | Copyright (C) 1996-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include 22 | #endif 23 | 24 | #include "argp.h" 25 | 26 | /* If set by the user program to a non-zero value, then a default option 27 | --version is added (unless the ARGP_NO_HELP flag is used), which calls 28 | this function with a stream to print the version to and a pointer to the 29 | current parsing state, and then exits (unless the ARGP_NO_EXIT flag is 30 | used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ 31 | void (*argp_program_version_hook) (FILE *stream, struct argp_state *state); 32 | -------------------------------------------------------------------------------- /argp-test.c: -------------------------------------------------------------------------------- 1 | /* Test program for argp argument parser 2 | Copyright (C) 1997-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | #ifndef _GNU_SOURCE 21 | # define _GNU_SOURCE 1 22 | #endif 23 | 24 | #ifdef HAVE_CONFIG_H 25 | #include 26 | #endif 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | const char *argp_program_version = "argp-test 1.0"; 34 | 35 | struct argp_option sub_options[] = 36 | { 37 | {"subopt1", 's', 0, 0, "Nested option 1"}, 38 | {"subopt2", 'S', 0, 0, "Nested option 2"}, 39 | 40 | { 0, 0, 0, 0, "Some more nested options:", 10}, 41 | {"subopt3", 'p', 0, 0, "Nested option 3"}, 42 | 43 | {"subopt4", 'q', 0, 0, "Nested option 4", 1}, 44 | 45 | {0} 46 | }; 47 | 48 | static const char sub_args_doc[] = "STRING...\n-"; 49 | static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser."; 50 | 51 | static error_t 52 | sub_parse_opt (int key, char *arg, struct argp_state *state) 53 | { 54 | switch (key) 55 | { 56 | case ARGP_KEY_NO_ARGS: 57 | printf ("NO SUB ARGS\n"); 58 | break; 59 | case ARGP_KEY_ARG: 60 | printf ("SUB ARG: %s\n", arg); 61 | break; 62 | 63 | case 's' : case 'S': case 'p': case 'q': 64 | printf ("SUB KEY %c\n", key); 65 | break; 66 | 67 | default: 68 | return ARGP_ERR_UNKNOWN; 69 | } 70 | return 0; 71 | } 72 | 73 | static char * 74 | sub_help_filter (int key, const char *text, void *input) 75 | { 76 | if (key == ARGP_KEY_HELP_EXTRA) 77 | return strdup ("This is some extra text from the sub parser (note that it \ 78 | is preceded by a blank line)."); 79 | else 80 | return (char *)text; 81 | } 82 | 83 | static struct argp sub_argp = { 84 | sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter 85 | }; 86 | 87 | /* Structure used to communicate with the parsing functions. */ 88 | struct params 89 | { 90 | unsigned foonly; /* Value parsed for foonly. */ 91 | unsigned foonly_default; /* Default value for it. */ 92 | }; 93 | 94 | #define OPT_PGRP 1 95 | #define OPT_SESS 2 96 | 97 | struct argp_option options[] = 98 | { 99 | {"pid", 'p', "PID", 0, "List the process PID"}, 100 | {"pgrp", OPT_PGRP,"PGRP",0, "List processes in the process group PGRP"}, 101 | {"no-parent", 'P', 0, 0, "Include processes without parents"}, 102 | {0, 'x', 0, OPTION_ALIAS}, 103 | {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally" 104 | " if there's some reason ps can't" 105 | " print a field for any process, it's" 106 | " removed from the output entirely)" }, 107 | {"reverse", 'r', 0, 0, "Reverse the order of any sort"}, 108 | {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, 109 | {"session", OPT_SESS,"SID", OPTION_ARG_OPTIONAL, 110 | "Add the processes from the session" 111 | " SID (which defaults to the sid of" 112 | " the current process)" }, 113 | 114 | {0,0,0,0, "Here are some more options:"}, 115 | {"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly"}, 116 | {"zaza", 'z', 0, 0, "Snit a zar"}, 117 | 118 | {0} 119 | }; 120 | 121 | static const char args_doc[] = "STRING"; 122 | static const char doc[] = "Test program for argp." 123 | "\vThis doc string comes after the options." 124 | "\nHey! Some manual formatting!" 125 | "\nThe current time is: %s"; 126 | 127 | static void 128 | popt (int key, char *arg) 129 | { 130 | char buf[12]; 131 | if (isprint (key)) 132 | sprintf (buf, "%c", key); 133 | else 134 | sprintf (buf, "%d", key); 135 | if (arg) 136 | printf ("KEY %s: %s\n", buf, arg); 137 | else 138 | printf ("KEY %s\n", buf); 139 | } 140 | 141 | static error_t 142 | parse_opt (int key, char *arg, struct argp_state *state) 143 | { 144 | struct params *params = state->input; 145 | 146 | switch (key) 147 | { 148 | case ARGP_KEY_NO_ARGS: 149 | printf ("NO ARGS\n"); 150 | break; 151 | 152 | case ARGP_KEY_ARG: 153 | if (state->arg_num > 0) 154 | return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser. */ 155 | printf ("ARG: %s\n", arg); 156 | break; 157 | 158 | case 'f': 159 | if (arg) 160 | params->foonly = atoi (arg); 161 | else 162 | params->foonly = params->foonly_default; 163 | popt (key, arg); 164 | break; 165 | 166 | case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q': 167 | case 'r': case OPT_SESS: case 'z': 168 | popt (key, arg); 169 | break; 170 | 171 | default: 172 | return ARGP_ERR_UNKNOWN; 173 | } 174 | return 0; 175 | } 176 | 177 | static char * 178 | help_filter (int key, const char *text, void *input) 179 | { 180 | char *new_text; 181 | struct params *params = input; 182 | 183 | if (key == ARGP_KEY_HELP_POST_DOC && text) 184 | { 185 | time_t now = time (0); 186 | asprintf (&new_text, text, ctime (&now)); 187 | } 188 | else if (key == 'f') 189 | /* Show the default for the --foonly option. */ 190 | asprintf (&new_text, "%s (ZOT defaults to %x)", 191 | text, params->foonly_default); 192 | else 193 | new_text = (char *)text; 194 | 195 | return new_text; 196 | } 197 | 198 | static struct argp_child argp_children[] = { { &sub_argp }, { 0 } }; 199 | static struct argp argp = { 200 | options, parse_opt, args_doc, doc, argp_children, help_filter 201 | }; 202 | 203 | int 204 | main (int argc, char **argv) 205 | { 206 | struct params params; 207 | params.foonly = 0; 208 | params.foonly_default = random (); 209 | argp_parse (&argp, argc, argv, 0, 0, ¶ms); 210 | printf ("After parsing: foonly = %x\n", params.foonly); 211 | return 0; 212 | } 213 | -------------------------------------------------------------------------------- /argp.h: -------------------------------------------------------------------------------- 1 | /* Hierarchical argument parsing, layered over getopt. 2 | Copyright (C) 1995-2021 Free Software Foundation, Inc. 3 | This file is part of the GNU C Library. 4 | Written by Miles Bader . 5 | 6 | The GNU C Library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | The GNU C Library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with the GNU C Library; if not, see 18 | . */ 19 | 20 | #ifndef _ARGP_H 21 | #define _ARGP_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | /* From glibc's */ 30 | # if (defined __cplusplus \ 31 | || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) 32 | # define __inline inline 33 | # else 34 | # define __inline /* No inline functions. */ 35 | # endif 36 | 37 | # define __THROW 38 | # define __THROWNL 39 | # define __NTH(fct) fct 40 | 41 | /* FIXME: conflict? */ 42 | typedef int error_t; 43 | 44 | /* FIXME: What's the right way to check for __restrict? Sun's cc seems 45 | not to have it. Perhaps it's easiest to just delete the use of 46 | __restrict from the prototypes. */ 47 | #ifndef __restrict 48 | # ifndef __GNUC___ 49 | # define __restrict 50 | # endif 51 | #endif 52 | 53 | /* NOTE: We can't use the autoconf tests, since this is supposed to be 54 | an installed header file and argp's config.h is of course not 55 | installed. */ 56 | #ifndef PRINTF_STYLE 57 | # if __GNUC__ >= 2 58 | # define PRINTF_STYLE(f, a) __attribute__ ((__format__ (__printf__, f, a))) 59 | # else 60 | # define PRINTF_STYLE(f, a) 61 | # endif 62 | #endif 63 | 64 | 65 | #ifdef __cplusplus 66 | extern "C" { 67 | #endif 68 | /* A description of a particular option. A pointer to an array of 69 | these is passed in the OPTIONS field of an argp structure. Each option 70 | entry can correspond to one long option and/or one short option; more 71 | names for the same option can be added by following an entry in an option 72 | array with options having the OPTION_ALIAS flag set. */ 73 | struct argp_option 74 | { 75 | /* The long option name. For more than one name for the same option, you 76 | can use following options with the OPTION_ALIAS flag set. */ 77 | const char *name; 78 | 79 | /* What key is returned for this option. If > 0 and printable, then it's 80 | also accepted as a short option. */ 81 | int key; 82 | 83 | /* If non-NULL, this is the name of the argument associated with this 84 | option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */ 85 | const char *arg; 86 | 87 | /* OPTION_ flags. */ 88 | int flags; 89 | 90 | /* The doc string for this option. If both NAME and KEY are 0, This string 91 | will be printed outdented from the normal option column, making it 92 | useful as a group header (it will be the first thing printed in its 93 | group); in this usage, it's conventional to end the string with a `:'. */ 94 | const char *doc; 95 | 96 | /* The group this option is in. In a long help message, options are sorted 97 | alphabetically within each group, and the groups presented in the order 98 | 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with 99 | if this field 0 will inherit the group number of the previous entry, or 100 | zero if it's the first one, unless its a group header (NAME and KEY both 101 | 0), in which case, the previous entry + 1 is the default. Automagic 102 | options such as --help are put into group -1. */ 103 | int group; 104 | }; 105 | 106 | /* The argument associated with this option is optional. */ 107 | #define OPTION_ARG_OPTIONAL 0x1 108 | 109 | /* This option isn't displayed in any help messages. */ 110 | #define OPTION_HIDDEN 0x2 111 | 112 | /* This option is an alias for the closest previous non-alias option. This 113 | means that it will be displayed in the same help entry, and will inherit 114 | fields other than NAME and KEY from the aliased option. */ 115 | #define OPTION_ALIAS 0x4 116 | 117 | /* This option isn't actually an option (and so should be ignored by the 118 | actual option parser), but rather an arbitrary piece of documentation that 119 | should be displayed in much the same manner as the options. If this flag 120 | is set, then the option NAME field is displayed unmodified (e.g., no `--' 121 | prefix is added) at the left-margin (where a *short* option would normally 122 | be displayed), and the documentation string in the normal place. For 123 | purposes of sorting, any leading whitespace and punctuation is ignored, 124 | except that if the first non-whitespace character is not `-', this entry 125 | is displayed after all options (and OPTION_DOC entries with a leading `-') 126 | in the same group. */ 127 | #define OPTION_DOC 0x8 128 | 129 | /* This option shouldn't be included in `long' usage messages (but is still 130 | included in help messages). This is mainly intended for options that are 131 | completely documented in an argp's ARGS_DOC field, in which case including 132 | the option in the generic usage list would be redundant. For instance, 133 | if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to 134 | distinguish these two cases, -x should probably be marked 135 | OPTION_NO_USAGE. */ 136 | #define OPTION_NO_USAGE 0x10 137 | 138 | struct argp; /* fwd declare this type */ 139 | struct argp_state; /* " */ 140 | struct argp_child; /* " */ 141 | 142 | /* The type of a pointer to an argp parsing function. */ 143 | typedef error_t (*argp_parser_t) (int __key, char *__arg, 144 | struct argp_state *__state); 145 | 146 | /* What to return for unrecognized keys. For special ARGP_KEY_ keys, such 147 | returns will simply be ignored. For user keys, this error will be turned 148 | into EINVAL (if the call to argp_parse is such that errors are propagated 149 | back to the user instead of exiting); returning EINVAL itself would result 150 | in an immediate stop to parsing in *all* cases. */ 151 | #define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */ 152 | 153 | /* Special values for the KEY argument to an argument parsing function. 154 | ARGP_ERR_UNKNOWN should be returned if they aren't understood. 155 | 156 | The sequence of keys to a parsing function is either (where each 157 | uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key): 158 | 159 | INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all 160 | or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed 161 | or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized 162 | 163 | The third case is where every parser returned ARGP_KEY_UNKNOWN for an 164 | argument, in which case parsing stops at that argument (returning the 165 | unparsed arguments to the caller of argp_parse if requested, or stopping 166 | with an error message if not). 167 | 168 | If an error occurs (either detected by argp, or because the parsing 169 | function returned an error value), then the parser is called with 170 | ARGP_KEY_ERROR, and no further calls are made. */ 171 | 172 | /* This is not an option at all, but rather a command line argument. If a 173 | parser receiving this key returns success, the fact is recorded, and the 174 | ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the 175 | argument, a parser function decrements the NEXT field of the state it's 176 | passed, the option won't be considered processed; this is to allow you to 177 | actually modify the argument (perhaps into an option), and have it 178 | processed again. */ 179 | #define ARGP_KEY_ARG 0 180 | /* There are remaining arguments not parsed by any parser, which may be found 181 | starting at (STATE->argv + STATE->next). If success is returned, but 182 | STATE->next left untouched, it's assumed that all arguments were consume, 183 | otherwise, the parser should adjust STATE->next to reflect any arguments 184 | consumed. */ 185 | #define ARGP_KEY_ARGS 0x1000006 186 | /* There are no more command line arguments at all. */ 187 | #define ARGP_KEY_END 0x1000001 188 | /* Because it's common to want to do some special processing if there aren't 189 | any non-option args, user parsers are called with this key if they didn't 190 | successfully process any non-option arguments. Called just before 191 | ARGP_KEY_END (where more general validity checks on previously parsed 192 | arguments can take place). */ 193 | #define ARGP_KEY_NO_ARGS 0x1000002 194 | /* Passed in before any parsing is done. Afterwards, the values of each 195 | element of the CHILD_INPUT field, if any, in the state structure is 196 | copied to each child's state to be the initial value of the INPUT field. */ 197 | #define ARGP_KEY_INIT 0x1000003 198 | /* Use after all other keys, including SUCCESS & END. */ 199 | #define ARGP_KEY_FINI 0x1000007 200 | /* Passed in when parsing has successfully been completed (even if there are 201 | still arguments remaining). */ 202 | #define ARGP_KEY_SUCCESS 0x1000004 203 | /* Passed in if an error occurs. */ 204 | #define ARGP_KEY_ERROR 0x1000005 205 | 206 | /* An argp structure contains a set of options declarations, a function to 207 | deal with parsing one, documentation string, a possible vector of child 208 | argp's, and perhaps a function to filter help output. When actually 209 | parsing options, getopt is called with the union of all the argp 210 | structures chained together through their CHILD pointers, with conflicts 211 | being resolved in favor of the first occurrence in the chain. */ 212 | struct argp 213 | { 214 | /* An array of argp_option structures, terminated by an entry with both 215 | NAME and KEY having a value of 0. */ 216 | const struct argp_option *options; 217 | 218 | /* What to do with an option from this structure. KEY is the key 219 | associated with the option, and ARG is any associated argument (NULL if 220 | none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be 221 | returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then 222 | parsing is stopped immediately, and that value is returned from 223 | argp_parse(). For special (non-user-supplied) values of KEY, see the 224 | ARGP_KEY_ definitions below. */ 225 | argp_parser_t parser; 226 | 227 | /* A string describing what other arguments are wanted by this program. It 228 | is only used by argp_usage to print the `Usage:' message. If it 229 | contains newlines, the strings separated by them are considered 230 | alternative usage patterns, and printed on separate lines (lines after 231 | the first are prefix by ` or: ' instead of `Usage:'). */ 232 | const char *args_doc; 233 | 234 | /* If non-NULL, a string containing extra text to be printed before and 235 | after the options in a long help message (separated by a vertical tab 236 | `\v' character). */ 237 | const char *doc; 238 | 239 | /* A vector of argp_children structures, terminated by a member with a 0 240 | argp field, pointing to child argps should be parsed with this one. Any 241 | conflicts are resolved in favor of this argp, or early argps in the 242 | CHILDREN list. This field is useful if you use libraries that supply 243 | their own argp structure, which you want to use in conjunction with your 244 | own. */ 245 | const struct argp_child *children; 246 | 247 | /* If non-zero, this should be a function to filter the output of help 248 | messages. KEY is either a key from an option, in which case TEXT is 249 | that option's help text, or a special key from the ARGP_KEY_HELP_ 250 | defines, below, describing which other help text TEXT is. The function 251 | should return either TEXT, if it should be used as-is, a replacement 252 | string, which should be malloced, and will be freed by argp, or NULL, 253 | meaning `print nothing'. The value for TEXT is *after* any translation 254 | has been done, so if any of the replacement text also needs translation, 255 | that should be done by the filter function. INPUT is either the input 256 | supplied to argp_parse, or NULL, if argp_help was called directly. */ 257 | char *(*help_filter) (int __key, const char *__text, void *__input); 258 | 259 | /* If non-zero the strings used in the argp library are translated using 260 | the domain described by this string. Otherwise the currently installed 261 | default domain is used. */ 262 | const char *argp_domain; 263 | }; 264 | 265 | /* Possible KEY arguments to a help filter function. */ 266 | #define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceding options. */ 267 | #define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */ 268 | #define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */ 269 | #define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation; 270 | TEXT is NULL for this key. */ 271 | /* Explanatory note emitted when duplicate option arguments have been 272 | suppressed. */ 273 | #define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005 274 | #define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */ 275 | 276 | /* When an argp has a non-zero CHILDREN field, it should point to a vector of 277 | argp_child structures, each of which describes a subsidiary argp. */ 278 | struct argp_child 279 | { 280 | /* The child parser. */ 281 | const struct argp *argp; 282 | 283 | /* Flags for this child. */ 284 | int flags; 285 | 286 | /* If non-zero, an optional header to be printed in help output before the 287 | child options. As a side-effect, a non-zero value forces the child 288 | options to be grouped together; to achieve this effect without actually 289 | printing a header string, use a value of "". */ 290 | const char *header; 291 | 292 | /* Where to group the child options relative to the other (`consolidated') 293 | options in the parent argp; the values are the same as the GROUP field 294 | in argp_option structs, but all child-groupings follow parent options at 295 | a particular group level. If both this field and HEADER are zero, then 296 | they aren't grouped at all, but rather merged with the parent options 297 | (merging the child's grouping levels with the parents). */ 298 | int group; 299 | }; 300 | 301 | /* Parsing state. This is provided to parsing functions called by argp, 302 | which may examine and, as noted, modify fields. */ 303 | struct argp_state 304 | { 305 | /* The top level ARGP being parsed. */ 306 | const struct argp *root_argp; 307 | 308 | /* The argument vector being parsed. May be modified. */ 309 | int argc; 310 | char **argv; 311 | 312 | /* The index in ARGV of the next arg that to be parsed. May be modified. */ 313 | int next; 314 | 315 | /* The flags supplied to argp_parse. May be modified. */ 316 | unsigned flags; 317 | 318 | /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the 319 | number of the current arg, starting at zero, and incremented after each 320 | such call returns. At all other times, this is the number of such 321 | arguments that have been processed. */ 322 | unsigned arg_num; 323 | 324 | /* If non-zero, the index in ARGV of the first argument following a special 325 | `--' argument (which prevents anything following being interpreted as an 326 | option). Only set once argument parsing has proceeded past this point. */ 327 | int quoted; 328 | 329 | /* An arbitrary pointer passed in from the user. */ 330 | void *input; 331 | /* Values to pass to child parsers. This vector will be the same length as 332 | the number of children for the current parser. */ 333 | void **child_inputs; 334 | 335 | /* For the parser's use. Initialized to 0. */ 336 | void *hook; 337 | 338 | /* The name used when printing messages. This is initialized to ARGV[0], 339 | or PROGRAM_INVOCATION_NAME if that is unavailable. */ 340 | char *name; 341 | 342 | /* Streams used when argp prints something. */ 343 | FILE *err_stream; /* For errors; initialized to stderr. */ 344 | FILE *out_stream; /* For information; initialized to stdout. */ 345 | 346 | void *pstate; /* Private, for use by argp. */ 347 | }; 348 | 349 | /* Flags for argp_parse (note that the defaults are those that are 350 | convenient for program command line parsing): */ 351 | 352 | /* Don't ignore the first element of ARGV. Normally (and always unless 353 | ARGP_NO_ERRS is set) the first element of the argument vector is 354 | skipped for option parsing purposes, as it corresponds to the program name 355 | in a command line. */ 356 | #define ARGP_PARSE_ARGV0 0x01 357 | 358 | /* Don't print error messages for unknown options to stderr; unless this flag 359 | is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program 360 | name in the error messages. This flag implies ARGP_NO_EXIT (on the 361 | assumption that silent exiting upon errors is bad behaviour). */ 362 | #define ARGP_NO_ERRS 0x02 363 | 364 | /* Don't parse any non-option args. Normally non-option args are parsed by 365 | calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg 366 | as the value. Since it's impossible to know which parse function wants to 367 | handle it, each one is called in turn, until one returns 0 or an error 368 | other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the 369 | argp_parse returns prematurely (but with a return value of 0). If all 370 | args have been parsed without error, all parsing functions are called one 371 | last time with a key of ARGP_KEY_END. This flag needn't normally be set, 372 | as the normal behavior is to stop parsing as soon as some argument can't 373 | be handled. */ 374 | #define ARGP_NO_ARGS 0x04 375 | 376 | /* Parse options and arguments in the same order they occur on the command 377 | line -- normally they're rearranged so that all options come first. */ 378 | #define ARGP_IN_ORDER 0x08 379 | 380 | /* Don't provide the standard long option --help, which causes usage and 381 | option help information to be output to stdout, and exit (0) called. */ 382 | #define ARGP_NO_HELP 0x10 383 | 384 | /* Don't exit on errors (they may still result in error messages). */ 385 | #define ARGP_NO_EXIT 0x20 386 | 387 | /* Use the gnu getopt `long-only' rules for parsing arguments. */ 388 | #define ARGP_LONG_ONLY 0x40 389 | 390 | /* Turns off any message-printing/exiting options. */ 391 | #define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP) 392 | 393 | /* Parse the options strings in ARGC & ARGV according to the options in ARGP. 394 | FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the 395 | index in ARGV of the first unparsed option is returned in it. If an 396 | unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser 397 | routine returned a non-zero value, it is returned; otherwise 0 is 398 | returned. This function may also call exit unless the ARGP_NO_HELP flag 399 | is set. INPUT is a pointer to a value to be passed in to the parser. */ 400 | extern error_t argp_parse (const struct argp *__restrict __argp, 401 | int __argc, char **__restrict __argv, 402 | unsigned __flags, int *__restrict __arg_index, 403 | void *__restrict __input); 404 | extern error_t __argp_parse (const struct argp *__restrict __argp, 405 | int __argc, char **__restrict __argv, 406 | unsigned __flags, int *__restrict __arg_index, 407 | void *__restrict __input); 408 | 409 | /* Global variables. */ 410 | 411 | /* If defined or set by the user program to a non-zero value, then a default 412 | option --version is added (unless the ARGP_NO_HELP flag is used), which 413 | will print this string followed by a newline and exit (unless the 414 | ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */ 415 | extern const char *argp_program_version; 416 | 417 | /* If defined or set by the user program to a non-zero value, then a default 418 | option --version is added (unless the ARGP_NO_HELP flag is used), which 419 | calls this function with a stream to print the version to and a pointer to 420 | the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is 421 | used). This variable takes precedent over ARGP_PROGRAM_VERSION. */ 422 | extern void (*argp_program_version_hook) (FILE *__restrict __stream, 423 | struct argp_state *__restrict 424 | __state); 425 | 426 | /* If defined or set by the user program, it should point to string that is 427 | the bug-reporting address for the program. It will be printed by 428 | argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various 429 | standard help messages), embedded in a sentence that says something like 430 | `Report bugs to ADDR.'. */ 431 | extern const char *argp_program_bug_address; 432 | 433 | /* The exit status that argp will use when exiting due to a parsing error. 434 | If not defined or set by the user program, this defaults to EX_USAGE from 435 | . */ 436 | extern error_t argp_err_exit_status; 437 | 438 | /* Flags for argp_help. */ 439 | #define ARGP_HELP_USAGE 0x01 /* a Usage: message. */ 440 | #define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */ 441 | #define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */ 442 | #define ARGP_HELP_LONG 0x08 /* a long help message. */ 443 | #define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */ 444 | #define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */ 445 | #define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC) 446 | #define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */ 447 | #define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to 448 | reflect ARGP_LONG_ONLY mode. */ 449 | 450 | /* These ARGP_HELP flags are only understood by argp_state_help. */ 451 | #define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */ 452 | #define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */ 453 | 454 | /* The standard thing to do after a program command line parsing error, if an 455 | error message has already been printed. */ 456 | #define ARGP_HELP_STD_ERR \ 457 | (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) 458 | /* The standard thing to do after a program command line parsing error, if no 459 | more specific error message has been printed. */ 460 | #define ARGP_HELP_STD_USAGE \ 461 | (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR) 462 | /* The standard thing to do in response to a --help option. */ 463 | #define ARGP_HELP_STD_HELP \ 464 | (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \ 465 | | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR) 466 | 467 | /* Output a usage message for ARGP to STREAM. FLAGS are from the set 468 | ARGP_HELP_*. */ 469 | extern void argp_help (const struct argp *__restrict __argp, 470 | FILE *__restrict __stream, 471 | unsigned __flags, char *__restrict __name); 472 | extern void __argp_help (const struct argp *__restrict __argp, 473 | FILE *__restrict __stream, unsigned __flags, 474 | char *__name); 475 | 476 | /* The following routines are intended to be called from within an argp 477 | parsing routine (thus taking an argp_state structure as the first 478 | argument). They may or may not print an error message and exit, depending 479 | on the flags in STATE -- in any case, the caller should be prepared for 480 | them *not* to exit, and should return an appropriate error after calling 481 | them. [argp_usage & argp_error should probably be called argp_state_..., 482 | but they're used often enough that they should be short] */ 483 | 484 | /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are 485 | from the set ARGP_HELP_*. */ 486 | extern void argp_state_help (const struct argp_state *__restrict __state, 487 | FILE *__restrict __stream, 488 | unsigned int __flags); 489 | extern void __argp_state_help (const struct argp_state *__restrict __state, 490 | FILE *__restrict __stream, 491 | unsigned int __flags); 492 | 493 | /* If appropriate, print the printf string FMT and following args, preceded 494 | by the program name and `:', to stderr, and followed by a `Try ... --help' 495 | message, then exit (1). */ 496 | extern void argp_error (const struct argp_state *__restrict __state, 497 | const char *__restrict __fmt, ...) 498 | PRINTF_STYLE(2,3); 499 | extern void __argp_error (const struct argp_state *__restrict __state, 500 | const char *__restrict __fmt, ...) 501 | PRINTF_STYLE(2,3); 502 | 503 | /* Similar to the standard gnu error-reporting function error(), but will 504 | respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print 505 | to STATE->err_stream. This is useful for argument parsing code that is 506 | shared between program startup (when exiting is desired) and runtime 507 | option parsing (when typically an error code is returned instead). The 508 | difference between this function and argp_error is that the latter is for 509 | *parsing errors*, and the former is for other problems that occur during 510 | parsing but don't reflect a (syntactic) problem with the input. */ 511 | extern void argp_failure (const struct argp_state *__restrict __state, 512 | int __status, int __errnum, 513 | const char *__restrict __fmt, ...) 514 | PRINTF_STYLE(4,5); 515 | extern void __argp_failure (const struct argp_state *__restrict __state, 516 | int __status, int __errnum, 517 | const char *__restrict __fmt, ...) 518 | PRINTF_STYLE(4,5); 519 | 520 | /* Return the input field for ARGP in the parser corresponding to STATE; used 521 | by the help routines. */ 522 | extern void *_argp_input (const struct argp *__restrict __argp, 523 | const struct argp_state *__restrict __state) 524 | __THROW; 525 | extern void *__argp_input (const struct argp *__restrict __argp, 526 | const struct argp_state *__restrict __state) 527 | __THROW; 528 | 529 | #if 1 530 | 531 | # if 1 532 | # define __argp_usage argp_usage 533 | # define __argp_state_help argp_state_help 534 | # define __option_is_short _option_is_short 535 | # define __option_is_end _option_is_end 536 | # endif 537 | 538 | # ifndef ARGP_EI 539 | # define ARGP_EI static __inline 540 | # endif 541 | 542 | /* Possibly output the standard usage message for ARGP to stderr and exit. */ 543 | ARGP_EI void 544 | __argp_usage (const struct argp_state *__state) 545 | { 546 | __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE); 547 | } 548 | 549 | /* Returns true if the option OPT is a valid short option. */ 550 | ARGP_EI int 551 | __NTH (__option_is_short (const struct argp_option *__opt)) 552 | { 553 | if (__opt->flags & OPTION_DOC) 554 | return 0; 555 | else 556 | { 557 | int __key = __opt->key; 558 | return __key > 0 && __key <= UCHAR_MAX && isprint (__key); 559 | } 560 | } 561 | 562 | /* Returns true if the option OPT is in fact the last (unused) entry in an 563 | options array. */ 564 | ARGP_EI int 565 | __NTH (__option_is_end (const struct argp_option *__opt)) 566 | { 567 | return !__opt->key && !__opt->name && !__opt->doc && !__opt->group; 568 | } 569 | 570 | # if 1 571 | # undef __argp_usage 572 | # undef __argp_state_help 573 | # undef __option_is_short 574 | # undef __option_is_end 575 | # endif 576 | #endif /* Use extern inlines. */ 577 | 578 | #ifdef __cplusplus 579 | } 580 | #endif 581 | 582 | #endif /* argp.h */ 583 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl Process this file with autoconf to produce a configure script. 2 | 3 | dnl This configure.ac is only for building a standalone argp library. 4 | AC_PREREQ(2.54) 5 | AC_INIT(argp-ba.c) 6 | AM_INIT_AUTOMAKE(argp, standalone-1.4.0) 7 | AM_CONFIG_HEADER(config.h) 8 | 9 | # GNU libc defaults to supplying the ISO C library functions only. The 10 | # _GNU_SOURCE define enables these extensions, in particular we want 11 | # errno.h to declare program_invocation_name. Enable it on all 12 | # systems; no problems have been reported with it so far. 13 | AC_GNU_SOURCE 14 | 15 | # Checks for programs. 16 | AC_PROG_CC 17 | AC_PROG_MAKE_SET 18 | AC_PROG_RANLIB 19 | AM_PROG_CC_STDC 20 | 21 | if test "x$am_cv_prog_cc_stdc" = xno ; then 22 | AC_ERROR([the C compiler doesn't handle ANSI-C]) 23 | fi 24 | 25 | # Checks for libraries. 26 | 27 | # Checks for header files. 28 | AC_HEADER_STDC 29 | AC_CHECK_HEADERS(limits.h malloc.h unistd.h libintl.h) 30 | 31 | # Checks for typedefs, structures, and compiler characteristics. 32 | AC_C_CONST 33 | AC_C_INLINE 34 | AC_TYPE_SIZE_T 35 | 36 | LSH_GCC_ATTRIBUTES 37 | 38 | # Checks for library functions. 39 | AC_FUNC_ALLOCA 40 | AC_FUNC_VPRINTF 41 | AC_CHECK_FUNCS(strerror) 42 | 43 | AC_REPLACE_FUNCS(mempcpy strndup strchrnul) 44 | 45 | dnl ARGP_CHECK_FUNC(includes, function-call [, if-found [, if-not-found]]) 46 | AC_DEFUN([ARGP_CHECK_FUNC], 47 | [AS_VAR_PUSHDEF([ac_func], m4_substr([$2], 0, m4_index([$2], [(]))) 48 | AS_VAR_PUSHDEF([ac_var], [ac_cv_func_call_]ac_func) 49 | AH_TEMPLATE(AS_TR_CPP(HAVE_[]ac_func), 50 | [Define to 1 if you have the `]ac_func[' function.]) 51 | AC_CACHE_CHECK([for $2], ac_var, 52 | [AC_TRY_LINK([$1], [$2], 53 | [AS_VAR_SET(ac_var, yes)], 54 | [AS_VAR_SET(ac_var, no)])]) 55 | if test AS_VAR_GET(ac_var) = yes ; then 56 | ifelse([$3],, 57 | [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_[]ac_func))], 58 | [$3 59 | ]) 60 | else 61 | ifelse([$4],, true, [$4]) 62 | fi 63 | AS_VAR_POPDEF([ac_var]) 64 | AS_VAR_POPDEF([ac_func]) 65 | ]) 66 | 67 | # At least on freebsd, putc_unlocked is a macro, so the standard 68 | # AC_CHECK_FUNCS doesn't work well. 69 | ARGP_CHECK_FUNC([#include ], [putc_unlocked('x', stdout)]) 70 | 71 | AC_CHECK_FUNCS(flockfile) 72 | AC_CHECK_FUNCS(fputs_unlocked fwrite_unlocked) 73 | 74 | # Used only by argp-test.c, so don't use AC_REPLACE_FUNCS. 75 | AC_CHECK_FUNCS(strdup asprintf) 76 | 77 | AC_CHECK_DECLS([program_invocation_name, program_invocation_short_name], 78 | [], [], [[#include ]]) 79 | 80 | # Set these flags *last*, or else the test programs won't compile 81 | if test x$GCC = xyes ; then 82 | # Using -ggdb3 makes (some versions of) Redhat's gcc-2.96 dump core 83 | if "$CC" --version | grep '^2\.96$' 1>/dev/null 2>&1; then 84 | true 85 | else 86 | CFLAGS="$CFLAGS -ggdb3" 87 | fi 88 | CFLAGS="$CFLAGS -Wall -W \ 89 | -Wmissing-prototypes -Wmissing-declarations -Wstrict-prototypes \ 90 | -Waggregate-return \ 91 | -Wpointer-arith -Wbad-function-cast -Wnested-externs" 92 | fi 93 | 94 | CPPFLAGS="$CPPFLAGS -I$srcdir" 95 | 96 | AC_OUTPUT(Makefile testsuite/Makefile) 97 | -------------------------------------------------------------------------------- /mempcpy.c: -------------------------------------------------------------------------------- 1 | /* strndup.c 2 | * 3 | */ 4 | 5 | /* Written by Niels Moeller 6 | * 7 | * This file is hereby placed in the public domain. 8 | */ 9 | 10 | #include 11 | 12 | void * 13 | mempcpy (void *to, const void *from, size_t size) 14 | { 15 | memcpy(to, from, size); 16 | return (char *) to + size; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /stamp-h.in: -------------------------------------------------------------------------------- 1 | timestamp 2 | -------------------------------------------------------------------------------- /strchrnul.c: -------------------------------------------------------------------------------- 1 | /* strchrnul.c 2 | * 3 | */ 4 | 5 | /* Written by Niels Moeller 6 | * 7 | * This file is hereby placed in the public domain. 8 | */ 9 | 10 | /* FIXME: What is this function supposed to do? My guess is that it is 11 | * like strchr, but returns a pointer to the NUL character, not a NULL 12 | * pointer, if the character isn't found. */ 13 | 14 | char *strchrnul(const char *s, int c) 15 | { 16 | const char *p = s; 17 | while (*p && (*p != c)) 18 | p++; 19 | 20 | return (char *) p; 21 | } 22 | -------------------------------------------------------------------------------- /strndup.c: -------------------------------------------------------------------------------- 1 | /* strndup.c 2 | * 3 | */ 4 | 5 | /* Written by Niels Moeller 6 | * 7 | * This file is hereby placed in the public domain. 8 | */ 9 | 10 | #include 11 | #include 12 | 13 | char * 14 | strndup (const char *s, size_t size) 15 | { 16 | char *r; 17 | char *end = memchr(s, 0, size); 18 | 19 | if (end) 20 | /* Length + 1 */ 21 | size = end - s + 1; 22 | 23 | r = malloc(size); 24 | 25 | if (size) 26 | { 27 | memcpy(r, s, size-1); 28 | r[size-1] = '\0'; 29 | } 30 | return r; 31 | } 32 | -------------------------------------------------------------------------------- /testsuite/Makefile.am: -------------------------------------------------------------------------------- 1 | TS_SH = ex1-test permute-test 2 | TS_PROGS = 3 | 4 | TS_ALL = $(TS_PROGS) $(TS_SH) 5 | 6 | noinst_PROGRAMS = $(TS_PROGS) ex1 ex3 ex4 7 | 8 | LDADD = ../libargp.a 9 | 10 | EXTRA_DIST = $(TS_SH) run-tests 11 | CLEANFILES = test.out 12 | 13 | .PHONY: check 14 | check: $(TS_ALL) $(srcdir)/run-tests 15 | srcdir="$(srcdir)" $(srcdir)/run-tests $(TS_ALL) 16 | -------------------------------------------------------------------------------- /testsuite/ex1-test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Success with no args 4 | ./ex1 || exit 1 5 | 6 | # Fail with args 7 | if ./ex1 foo 2>/dev/null ; then exit 1 ; fi 8 | 9 | # Respond to --help 10 | ./ex1 --help >/dev/null || exit 1 11 | 12 | # Not using ARGP_LONG_ONLY 13 | if ./ex1 -help 2>/dev/null ; then exit 1 ; fi 14 | 15 | (./ex1 --help | grep Usage: >/dev/null ) || exit 1 16 | 17 | exit 0 18 | 19 | -------------------------------------------------------------------------------- /testsuite/ex1.c: -------------------------------------------------------------------------------- 1 | /* Argp example #1 - a minimal program using argp */ 2 | 3 | /* This is (probably) the smallest possible program that 4 | uses argp. It won't do much except give an error 5 | messages and exit when there are any arguments, and print 6 | a (rather pointless) messages for -help. */ 7 | 8 | #include 9 | 10 | #include 11 | 12 | int main (int argc, char **argv) 13 | { 14 | argp_parse (0, argc, argv, 0, 0, 0); 15 | exit (0); 16 | } 17 | -------------------------------------------------------------------------------- /testsuite/ex3.c: -------------------------------------------------------------------------------- 1 | /* Argp example #3 - a program with options and arguments using argp */ 2 | 3 | /* This program uses the same features as example 2, and uses options and 4 | arguments. 5 | 6 | We now use the first four fields in ARGP, so here's a description of them: 7 | OPTIONS - A pointer to a vector of struct argp_option (see below) 8 | PARSER - A function to parse a single option, called by argp 9 | ARGS_DOC - A string describing how the non-option arguments should look 10 | DOC - A descriptive string about this program; if it contains a 11 | vertical tab character (\v), the part after it will be 12 | printed *following* the options 13 | 14 | The function PARSER takes the following arguments: 15 | KEY - An integer specifying which option this is (taken 16 | from the KEY field in each struct argp_option), or 17 | a special key specifying something else; the only 18 | special keys we use here are ARGP_KEY_ARG, meaning 19 | a non-option argument, and ARGP_KEY_END, meaning 20 | that all arguments have been parsed 21 | ARG - For an option KEY, the string value of its 22 | argument, or NULL if it has none 23 | STATE- A pointer to a struct argp_state, containing 24 | various useful information about the parsing state; used here 25 | are the INPUT field, which reflects the INPUT argument to 26 | argp_parse, and the ARG_NUM field, which is the number of the 27 | current non-option argument being parsed 28 | It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the 29 | given KEY wasn't recognized, or an errno value indicating some other 30 | error. 31 | 32 | Note that in this example, main uses a structure to communicate with the 33 | parse_opt function, a pointer to which it passes in the INPUT argument to 34 | argp_parse. Of course, it's also possible to use global variables 35 | instead, but this is somewhat more flexible. 36 | 37 | The OPTIONS field contains a pointer to a vector of struct argp_option's; 38 | that structure has the following fields (if you assign your option 39 | structures using array initialization like this example, unspecified 40 | fields will be defaulted to 0, and need not be specified): 41 | NAME - The name of this option's long option (may be zero) 42 | KEY - The KEY to pass to the PARSER function when parsing this option, 43 | *and* the name of this option's short option, if it is a 44 | printable ascii character 45 | ARG - The name of this option's argument, if any 46 | FLAGS - Flags describing this option; some of them are: 47 | OPTION_ARG_OPTIONAL - The argument to this option is optional 48 | OPTION_ALIAS - This option is an alias for the 49 | previous option 50 | OPTION_HIDDEN - Don't show this option in -help output 51 | DOC - A documentation string for this option, shown in -help output 52 | 53 | An options vector should be terminated by an option with all fields zero. */ 54 | 55 | #include 56 | 57 | #include 58 | 59 | const char *argp_program_version = 60 | "argp-ex3 1.0"; 61 | const char *argp_program_bug_address = 62 | ""; 63 | 64 | /* Program documentation. */ 65 | static char doc[] = 66 | "Argp example #3 -- a program with options and arguments using argp"; 67 | 68 | /* A description of the arguments we accept. */ 69 | static char args_doc[] = "ARG1 ARG2"; 70 | 71 | /* The options we understand. */ 72 | static struct argp_option options[] = { 73 | {"verbose", 'v', 0, 0, "Produce verbose output", 0}, 74 | {"quiet", 'q', 0, 0, "Don't produce any output", 0}, 75 | {"silent", 's', 0, OPTION_ALIAS, 0, 0}, 76 | {"output", 'o', "FILE", 0, 77 | "Output to FILE instead of standard output", 0}, 78 | {0, 0, 0, 0, 0, 0} 79 | }; 80 | 81 | /* Used by `main' to communicate with `parse_opt'. */ 82 | struct arguments 83 | { 84 | char *args[2]; /* ARG1 & ARG2 */ 85 | int silent, verbose; 86 | char *output_file; 87 | }; 88 | 89 | /* Parse a single option. */ 90 | static error_t 91 | parse_opt (int key, char *arg, struct argp_state *state) 92 | { 93 | /* Get the INPUT argument from `argp_parse', which we 94 | know is a pointer to our arguments structure. */ 95 | struct arguments *arguments = state->input; 96 | 97 | switch (key) 98 | { 99 | case 'q': case 's': 100 | arguments->silent = 1; 101 | break; 102 | case 'v': 103 | arguments->verbose = 1; 104 | break; 105 | case 'o': 106 | arguments->output_file = arg; 107 | break; 108 | 109 | case ARGP_KEY_ARG: 110 | if (state->arg_num >= 2) 111 | /* Too many arguments. */ 112 | argp_usage (state); 113 | 114 | arguments->args[state->arg_num] = arg; 115 | 116 | break; 117 | 118 | case ARGP_KEY_END: 119 | if (state->arg_num < 2) 120 | /* Not enough arguments. */ 121 | argp_usage (state); 122 | break; 123 | 124 | default: 125 | return ARGP_ERR_UNKNOWN; 126 | } 127 | return 0; 128 | } 129 | 130 | /* Our argp parser. */ 131 | static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 }; 132 | 133 | int main (int argc, char **argv) 134 | { 135 | struct arguments arguments; 136 | 137 | /* Default values. */ 138 | arguments.silent = 0; 139 | arguments.verbose = 0; 140 | arguments.output_file = "-"; 141 | 142 | /* Parse our arguments; every option seen by `parse_opt' will 143 | be reflected in `arguments'. */ 144 | argp_parse (&argp, argc, argv, 0, 0, &arguments); 145 | 146 | printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n" 147 | "VERBOSE = %s\nSILENT = %s\n", 148 | arguments.args[0], arguments.args[1], 149 | arguments.output_file, 150 | arguments.verbose ? "yes" : "no", 151 | arguments.silent ? "yes" : "no"); 152 | 153 | exit (0); 154 | } 155 | -------------------------------------------------------------------------------- /testsuite/ex4.c: -------------------------------------------------------------------------------- 1 | /* Argp example #4 - a program with somewhat more complicated options */ 2 | 3 | /* This program uses the same features as example 3, but has more 4 | options, and somewhat more structure in the -help output. It 5 | also shows how you can `steal' the remainder of the input 6 | arguments past a certain point, for programs that accept a 7 | list of items. It also shows the special argp KEY value 8 | ARGP_KEY_NO_ARGS, which is only given if no non-option 9 | arguments were supplied to the program. 10 | 11 | For structuring the help output, two features are used, 12 | *headers* which are entries in the options vector with the 13 | first four fields being zero, and a two part documentation 14 | string (in the variable DOC), which allows documentation both 15 | before and after the options; the two parts of DOC are 16 | separated by a vertical-tab character ('\v', or '\013'). By 17 | convention, the documentation before the options is just a 18 | short string saying what the program does, and that afterwards 19 | is longer, describing the behavior in more detail. All 20 | documentation strings are automatically filled for output, 21 | although newlines may be included to force a line break at a 22 | particular point. All documentation strings are also passed to 23 | the `gettext' function, for possible translation into the 24 | current locale. */ 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | const char *argp_program_version = 31 | "argp-ex4 1.0"; 32 | const char *argp_program_bug_address = 33 | ""; 34 | 35 | /* Program documentation. */ 36 | static char doc[] = 37 | "Argp example #4 -- a program with somewhat more complicated\ 38 | options\ 39 | \vThis part of the documentation comes *after* the options;\ 40 | note that the text is automatically filled, but it's possible\ 41 | to force a line-break, e.g.\n<-- here."; 42 | 43 | /* A description of the arguments we accept. */ 44 | static char args_doc[] = "ARG1 [STRING...]"; 45 | 46 | /* Keys for options without short-options. */ 47 | #define OPT_ABORT 1 /* -abort */ 48 | 49 | /* The options we understand. */ 50 | static struct argp_option options[] = { 51 | {"verbose", 'v', 0, 0, "Produce verbose output", 0}, 52 | {"quiet", 'q', 0, 0, "Don't produce any output", 0}, 53 | {"silent", 's', 0, OPTION_ALIAS, 0, 0}, 54 | {"output", 'o', "FILE", 0, 55 | "Output to FILE instead of standard output", 0}, 56 | 57 | {0,0,0,0, "The following options should be grouped together:", 0}, 58 | {"repeat", 'r', "COUNT", OPTION_ARG_OPTIONAL, 59 | "Repeat the output COUNT (default 10) times", 0}, 60 | {"abort", OPT_ABORT, 0, 0, "Abort before showing any output", 0}, 61 | 62 | {0, 0, 0, 0, 0, 0} 63 | }; 64 | 65 | /* Used by `main' to communicate with `parse_opt'. */ 66 | struct arguments 67 | { 68 | char *arg1; /* ARG1 */ 69 | char **strings; /* [STRING...] */ 70 | int silent, verbose, abort; /* `-s', `-v', `--abort' */ 71 | char *output_file; /* FILE arg to `--output' */ 72 | int repeat_count; /* COUNT arg to `--repeat' */ 73 | }; 74 | 75 | /* Parse a single option. */ 76 | static error_t 77 | parse_opt (int key, char *arg, struct argp_state *state) 78 | { 79 | /* Get the `input' argument from `argp_parse', which we 80 | know is a pointer to our arguments structure. */ 81 | struct arguments *arguments = state->input; 82 | 83 | switch (key) 84 | { 85 | case 'q': case 's': 86 | arguments->silent = 1; 87 | break; 88 | case 'v': 89 | arguments->verbose = 1; 90 | break; 91 | case 'o': 92 | arguments->output_file = arg; 93 | break; 94 | case 'r': 95 | arguments->repeat_count = arg ? atoi (arg) : 10; 96 | break; 97 | case OPT_ABORT: 98 | arguments->abort = 1; 99 | break; 100 | 101 | case ARGP_KEY_NO_ARGS: 102 | argp_usage (state); 103 | 104 | case ARGP_KEY_ARG: 105 | /* Here we know that `state->arg_num == 0', since we 106 | force argument parsing to end before any more arguments can 107 | get here. */ 108 | arguments->arg1 = arg; 109 | 110 | /* Now we consume all the rest of the arguments. 111 | `state->next' is the index in `state->argv' of the 112 | next argument to be parsed, which is the first STRING 113 | we're interested in, so we can just use 114 | `&state->argv[state->next]' as the value for 115 | arguments->strings. 116 | 117 | _In addition_, by setting `state->next' to the end 118 | of the arguments, we can force argp to stop parsing here and 119 | return. */ 120 | arguments->strings = &state->argv[state->next]; 121 | state->next = state->argc; 122 | 123 | break; 124 | 125 | default: 126 | return ARGP_ERR_UNKNOWN; 127 | } 128 | return 0; 129 | } 130 | 131 | /* Our argp parser. */ 132 | static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0}; 133 | 134 | int main (int argc, char **argv) 135 | { 136 | int i, j; 137 | struct arguments arguments; 138 | 139 | /* Default values. */ 140 | arguments.silent = 0; 141 | arguments.verbose = 0; 142 | arguments.output_file = "-"; 143 | arguments.repeat_count = 1; 144 | arguments.abort = 0; 145 | 146 | /* Parse our arguments; every option seen by `parse_opt' will be 147 | reflected in `arguments'. */ 148 | argp_parse (&argp, argc, argv, 0, 0, &arguments); 149 | 150 | if (arguments.abort) 151 | { 152 | /* The glibc example used error (10, 0, "ABORTED"), but that's 153 | not portable. */ 154 | fprintf(stderr, "ex4: ABORTED\n"); 155 | exit(10); 156 | } 157 | 158 | for (i = 0; i < arguments.repeat_count; i++) 159 | { 160 | printf ("ARG1 = %s\n", arguments.arg1); 161 | printf ("STRINGS = "); 162 | for (j = 0; arguments.strings[j]; j++) 163 | printf (j == 0 ? "%s" : ", %s", arguments.strings[j]); 164 | printf ("\n"); 165 | printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n", 166 | arguments.output_file, 167 | arguments.verbose ? "yes" : "no", 168 | arguments.silent ? "yes" : "no"); 169 | } 170 | 171 | exit (0); 172 | } 173 | -------------------------------------------------------------------------------- /testsuite/permute-test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Test the somewhat hairy permuting of arguments. 4 | 5 | cat >test.out <&2 15 | exit 1 16 | } 17 | 18 | for args in "-v foo bar" \ 19 | "-v -v foo bar" "-v foo -v bar" "-v foo bar -v" \ 20 | "foo -v bar -v" "foo bar -v -v" "foo -v -v bar" ; do 21 | ./ex3 $args | diff - test.out >/dev/null || die "Test failed with args $args" 22 | done 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /testsuite/run-tests: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | failed=0 4 | all=0 5 | 6 | if [ -z "$srcdir" ] ; then 7 | srcdir=`pwd` 8 | fi 9 | 10 | export srcdir 11 | 12 | find_program () { 13 | if [ -x "$1" ] ; then 14 | echo "./$1" 15 | else 16 | echo "$srcdir/$1" 17 | fi 18 | } 19 | 20 | env_program () { 21 | if [ -x "$1" ] ; then 22 | if "$1"; then : ; else 23 | echo FAIL: $1 24 | exit 1 25 | fi 26 | fi 27 | } 28 | 29 | test_program () { 30 | testname=`basename "$1" -test` 31 | "$1" 32 | case "$?" in 33 | 0) 34 | echo PASS: $testname 35 | all=`expr $all + 1` 36 | ;; 37 | 77) 38 | echo SKIP: $testname 39 | ;; 40 | *) 41 | echo FAIL: $testname 42 | failed=`expr $failed + 1` 43 | all=`expr $all + 1` 44 | ;; 45 | esac 46 | } 47 | 48 | env_program `find_program setup-env` 49 | 50 | if [ $# -eq 0 ] ; then 51 | for f in *-test; do test_program "./$f"; done 52 | else 53 | for f in "$@" ; do test_program `find_program "$f"`; done 54 | fi 55 | 56 | if [ $failed -eq 0 ] ; then 57 | banner="All $all tests passed" 58 | else 59 | banner="$failed of $all tests failed" 60 | fi 61 | dashes=`echo "$banner" | sed s/./=/g` 62 | echo "$dashes" 63 | echo "$banner" 64 | echo "$dashes" 65 | 66 | env_program `find_program teardown-env` 67 | 68 | [ "$failed" -eq 0 ] 69 | 70 | --------------------------------------------------------------------------------