Third-party libraries updated.
This commit is contained in:
parent
eae3e66694
commit
1aede80d34
42555 changed files with 948574 additions and 5092609 deletions
10
CHANGELOG
10
CHANGELOG
|
|
@ -152,6 +152,16 @@ API Changes
|
|||
layers, filter passes, mask writes, layer bytes, passes). Test scenes
|
||||
scene40 to scene43 cover clip masks, layers, filters and gradients.
|
||||
|
||||
- Third-party libraries brought up to their current releases: ffmpeg
|
||||
9.0.1 (from a 2023 development snapshot; libpostproc is gone with it),
|
||||
OpenSSL 3.5.8 LTS (from a 2023 development snapshot), Lua 5.4.9, zlib
|
||||
1.3.2, zstd 1.5.7, uthash 2.4.0, lsqlite3 0.9.7, luafilesystem 1.9.0,
|
||||
copas 4.12.0 (its new copas.future module is embedded) and arg_parser
|
||||
1.21. sqlite3.lversion() reports the real lsqlite3 version instead
|
||||
of "unknown", and os.tmpname() returns a usable name again (the local
|
||||
mkstemp edit never filled in its template). LICENSES now records the
|
||||
version of every vendored library.
|
||||
|
||||
- The bundled menu is an RmlUi document (Singe/Menu.rml styled by
|
||||
Singe/menu.rcss, filled and driven by Singe/Menu.singe): every game in
|
||||
a scrolling list on the left, up and down to select, left and right to
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ singeEmbedLua(thirdparty/luasec/src/ssl.lua "")
|
|||
singeEmbedLua(thirdparty/librs232/bindings/lua/rs232.lua "")
|
||||
singeEmbedLua(thirdparty/copas/src/copas.lua "")
|
||||
singeEmbedLua(thirdparty/copas/src/copas/ftp.lua "copas_")
|
||||
singeEmbedLua(thirdparty/copas/src/copas/future.lua "copas_")
|
||||
singeEmbedLua(thirdparty/copas/src/copas/http.lua "copas_")
|
||||
singeEmbedLua(thirdparty/copas/src/copas/smtp.lua "copas_")
|
||||
singeEmbedLua(thirdparty/copas/src/copas/lock.lua "copas_")
|
||||
|
|
@ -310,11 +311,14 @@ set(SINGE_SOURCE
|
|||
src/vfs.h
|
||||
)
|
||||
|
||||
# The binding reports this from sqlite3.lversion(); it is the version of thirdparty/lsqlite3/lsqlite3.c.
|
||||
set(LSQLITE_VERSION "0.9.7")
|
||||
set(SQLITE_SOURCE
|
||||
thirdparty/sqlite/sqlite3.c
|
||||
thirdparty/sqlite/sqlite3.h
|
||||
thirdparty/lsqlite3/lsqlite3.c
|
||||
)
|
||||
set_source_files_properties(thirdparty/lsqlite3/lsqlite3.c PROPERTIES COMPILE_DEFINITIONS "LSQLITE_VERSION=\"${LSQLITE_VERSION}\"")
|
||||
|
||||
set(ARG_PARSER_SOURCE
|
||||
thirdparty/arg_parser/carg_parser.c
|
||||
|
|
@ -627,7 +631,6 @@ set(STATIC_LIBS
|
|||
${BUILD_DIR}/lib/libopus.a
|
||||
${BUILD_DIR}/lib/libopusfile.a
|
||||
${BUILD_DIR}/lib/libogg.a
|
||||
${BUILD_DIR}/lib/libpostproc.a
|
||||
${BUILD_DIR}/lib/libSDL3.a
|
||||
${BUILD_DIR}/lib/libSDL3_image.a
|
||||
${BUILD_DIR}/lib/libSDL3_mixer.a
|
||||
|
|
|
|||
84
LICENSES
84
LICENSES
|
|
@ -2,47 +2,51 @@ Singe was made possible by a number of third-party software libraries
|
|||
generously provided as open source by their respective authors. Without
|
||||
these tools, Singe would not exist.
|
||||
|
||||
The version column is the release vendored under thirdparty/ (or, for the
|
||||
libraries bundled inside the SDL trees and the host tools, the copy those
|
||||
trees carry). Projects without releases are listed by snapshot date.
|
||||
|
||||
arg_parser BSD-2-Clause http://savannah.nongnu.org/projects/arg-parser
|
||||
basis_universal Apache-2.0 https://github.com/BinomialLLC/basis_universal
|
||||
binaryheap.lua MIT http://tieske.github.io/binaryheap.lua
|
||||
cgltf MIT https://github.com/jkuhlmann/cgltf
|
||||
DirectXShaderCompiler NCSA https://github.com/microsoft/DirectXShaderCompiler (prebuilt, downloaded at build time; host tool only)
|
||||
copas MIT https://lunarmodules.github.io/copas
|
||||
ffmpeg LGPL-2.1 https://ffmpeg.org
|
||||
freetype FTL https://freetype.org
|
||||
JoltPhysics MIT https://github.com/jrouwe/JoltPhysics
|
||||
json.lua MIT https://github.com/rxi/json.lua
|
||||
libjpeg-turbo IJG https://libjpeg-turbo.org
|
||||
libogg BSD-3-Clause https://xiph.org/ogg
|
||||
libpng libpng-2.0 http://www.libpng.org
|
||||
librs232 MIT https://github.com/srdgame/librs232
|
||||
libwebp BSD-3-Clause https://developers.google.com/speed/webp
|
||||
libxmp MIT https://github.com/libxmp/libxmp
|
||||
lsqlite3 MIT http://lua.sqlite.org
|
||||
lua MIT https://www.lua.org
|
||||
luafilesystem MIT https://lunarmodules.github.io/luafilesystem
|
||||
luasec MIT https://github.com/lunarmodules/luasec
|
||||
luasocket MIT https://lunarmodules.github.io/luasocket
|
||||
manymouse Zlib https://icculus.org/manymouse
|
||||
openssl Apache-2.0 https://www.openssl.org
|
||||
opus BSD-3-Clause https://opus-codec.org
|
||||
opusfile BSD-3-Clause https://opus-codec.org
|
||||
recastnavigation Zlib https://github.com/recastnavigation/recastnavigation
|
||||
RmlUi MIT https://github.com/mikke89/RmlUi
|
||||
SDL3 Zlib https://www.libsdl.org
|
||||
SDL_shadercross Zlib https://github.com/libsdl-org/SDL_shadercross (host tool only)
|
||||
SDL3_image Zlib https://www.libsdl.org
|
||||
SDL3_mixer Zlib https://www.libsdl.org
|
||||
SDL3_ttf Zlib https://www.libsdl.org
|
||||
SPIRV-Cross Apache-2.0 https://github.com/KhronosGroup/SPIRV-Cross (host tool only)
|
||||
sqlite Public-Domain https://sqlite.org
|
||||
timerwheel.lua MIT https://tieske.github.io/timerwheel.lua
|
||||
uthash BSD-1-Clause https://troydhanson.github.io/uthash
|
||||
vlc GPL-2.0 https://www.videolan.org/vlc
|
||||
wavpack BSD-3-Clause https://www.wavpack.com
|
||||
zlib Zlib https://zlib.net
|
||||
zstd BSD-3-Clause https://facebook.github.io/zstd
|
||||
|
||||
arg_parser 1.21 BSD-2-Clause http://savannah.nongnu.org/projects/arg-parser
|
||||
basis_universal 2.50 Apache-2.0 https://github.com/BinomialLLC/basis_universal
|
||||
binaryheap.lua 0.4 MIT http://tieske.github.io/binaryheap.lua
|
||||
cgltf 1.15 MIT https://github.com/jkuhlmann/cgltf
|
||||
copas 4.12.0 MIT https://lunarmodules.github.io/copas
|
||||
DirectXShaderCompiler 1.10.2605.37 NCSA https://github.com/microsoft/DirectXShaderCompiler (prebuilt, downloaded at build time; host tool only)
|
||||
ffmpeg 9.0.1 LGPL-2.1 https://ffmpeg.org
|
||||
freetype 2.13.2 FTL https://freetype.org (bundled with SDL3_ttf)
|
||||
JoltPhysics 5.6.0 MIT https://github.com/jrouwe/JoltPhysics
|
||||
json.lua 0.1.2 MIT https://github.com/rxi/json.lua
|
||||
libjpeg 9f IJG https://ijg.org (bundled with SDL3_image)
|
||||
libogg 1.3.5 BSD-3-Clause https://xiph.org/ogg (bundled with SDL3_mixer)
|
||||
libpng 1.6.58 libpng-2.0 http://www.libpng.org (bundled with SDL3_image)
|
||||
librs232 1.0.4 MIT https://github.com/srdgame/librs232
|
||||
libwebp 1.3.2 BSD-3-Clause https://developers.google.com/speed/webp (bundled with SDL3_image)
|
||||
libxmp 4.7.0 MIT https://github.com/libxmp/libxmp (bundled with SDL3_mixer)
|
||||
lsqlite3 0.9.7 MIT http://lua.sqlite.org
|
||||
lua 5.4.9 MIT https://www.lua.org
|
||||
luafilesystem 1.9.0 MIT https://lunarmodules.github.io/luafilesystem
|
||||
luasec 1.3.2 MIT https://github.com/lunarmodules/luasec
|
||||
luasocket 3.1.0 MIT https://lunarmodules.github.io/luasocket
|
||||
manymouse 0.0.3 Zlib https://icculus.org/manymouse
|
||||
openssl 3.5.8 Apache-2.0 https://www.openssl.org
|
||||
opus 1.4 BSD-3-Clause https://opus-codec.org (bundled with SDL3_mixer)
|
||||
opusfile 0.12 BSD-3-Clause https://opus-codec.org (bundled with SDL3_mixer)
|
||||
recastnavigation 1.6.0 Zlib https://github.com/recastnavigation/recastnavigation
|
||||
RmlUi 6.3 MIT https://github.com/mikke89/RmlUi
|
||||
SDL3 3.4.16 Zlib https://www.libsdl.org
|
||||
SDL_shadercross main 2026-09 Zlib https://github.com/libsdl-org/SDL_shadercross (host tool only)
|
||||
SDL3_image 3.4.6 Zlib https://www.libsdl.org
|
||||
SDL3_mixer 3.2.4 Zlib https://www.libsdl.org
|
||||
SDL3_ttf 3.2.2 Zlib https://www.libsdl.org
|
||||
SPIRV-Cross main 2026-09 Apache-2.0 https://github.com/KhronosGroup/SPIRV-Cross (host tool only)
|
||||
sqlite 3.53.4 Public-Domain https://sqlite.org
|
||||
timerwheel.lua 1.0.2 MIT https://tieske.github.io/timerwheel.lua
|
||||
uthash 2.4.0 BSD-1-Clause https://troydhanson.github.io/uthash
|
||||
vlc 3.0 headers LGPL-2.1 https://www.videolan.org/vlc (two language-code headers only)
|
||||
wavpack 5.9.0 BSD-3-Clause https://www.wavpack.com (bundled with SDL3_mixer)
|
||||
zlib 1.3.2 Zlib https://zlib.net
|
||||
zstd 1.5.7 BSD-3-Clause https://facebook.github.io/zstd
|
||||
|
||||
|
||||
Fonts
|
||||
|
|
|
|||
|
|
@ -134,12 +134,12 @@ function(singeCmakeProject name source deps args env)
|
|||
singeRebuildTarget(${name})
|
||||
endfunction()
|
||||
|
||||
# rebuild-<name> forgets the stamps and builds the library again, then whatever depends on it
|
||||
# rebuild-<name> forgets the stamps and the build directory and builds the library again, then whatever depends on it
|
||||
# is rebuilt by the normal build.
|
||||
function(singeRebuildTarget name)
|
||||
ExternalProject_Get_Property(${name} STAMP_DIR)
|
||||
ExternalProject_Get_Property(${name} STAMP_DIR BINARY_DIR)
|
||||
add_custom_target(rebuild-${name}
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf ${STAMP_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E rm -rf ${STAMP_DIR} ${BINARY_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${name}
|
||||
COMMENT "Rebuilding ${name}"
|
||||
)
|
||||
|
|
@ -240,7 +240,7 @@ elseif(KANGAROO_OS STREQUAL "pi")
|
|||
if(KANGAROO_ARCH STREQUAL "aarch64")
|
||||
set(opensslTarget linux-aarch64)
|
||||
else()
|
||||
set(opensslTarget linux-arm4)
|
||||
set(opensslTarget linux-armv4)
|
||||
endif()
|
||||
elseif(KANGAROO_OS STREQUAL "macos")
|
||||
if(KANGAROO_ARCH STREQUAL "aarch64")
|
||||
|
|
@ -316,7 +316,7 @@ set(ffmpegBinary ${SB_PREFIX}/build/ffmpeg)
|
|||
ExternalProject_Add(ffmpeg
|
||||
SOURCE_DIR ${SB_THIRDPARTY}/ffmpeg
|
||||
BINARY_DIR ${ffmpegBinary}
|
||||
CONFIGURE_COMMAND ${SB_ENV} ${SB_THIRDPARTY}/ffmpeg/configure --enable-static --disable-shared --disable-debug --disable-muxers ${hwaccel} --disable-encoders --disable-filters --disable-network --disable-devices --disable-bzlib --disable-lzma --disable-doc --disable-programs --enable-gpl --enable-version3 --extra-ldflags=-L${SB_PREFIX}/lib --prefix=${SB_PREFIX} --arch=${KANGAROO_ARCH} --target-os=${SINGE_CROSS_OS} ${ffmpegTools}
|
||||
CONFIGURE_COMMAND ${SB_ENV} ${SB_THIRDPARTY}/ffmpeg/configure --enable-static --disable-shared --disable-debug --disable-muxers ${hwaccel} --disable-encoders --disable-filters --disable-network --disable-devices --disable-vulkan --disable-d3d12va --disable-bzlib --disable-lzma --disable-doc --disable-programs --enable-gpl --enable-version3 --extra-ldflags=-L${SB_PREFIX}/lib --prefix=${SB_PREFIX} --arch=${KANGAROO_ARCH} --target-os=${SINGE_CROSS_OS} ${ffmpegTools}
|
||||
BUILD_COMMAND ${SB_ENV} make
|
||||
INSTALL_COMMAND ${SB_ENV} make install
|
||||
LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_OUTPUT_ON_FAILURE ON
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
// Copas
|
||||
#include "generated/copas_lua.h"
|
||||
#include "generated/copas_ftp_lua.h"
|
||||
#include "generated/copas_future_lua.h"
|
||||
#include "generated/copas_http_lua.h"
|
||||
#include "generated/copas_lock_lua.h"
|
||||
#include "generated/copas_queue_lua.h"
|
||||
|
|
|
|||
|
|
@ -1067,6 +1067,7 @@ static const LuaModuleT _luaModules[] = {
|
|||
// Copas
|
||||
MODL("copas", copas_lua),
|
||||
MODL("copas.ftp", copas_ftp_lua),
|
||||
MODL("copas.future", copas_future_lua),
|
||||
MODL("copas.http", copas_http_lua),
|
||||
MODL("copas.lock", copas_lock_lua),
|
||||
MODL("copas.queue", copas_queue_lua),
|
||||
|
|
|
|||
2
thirdparty/arg_parser/COPYING
vendored
2
thirdparty/arg_parser/COPYING
vendored
|
|
@ -1,4 +1,4 @@
|
|||
Arg_parser - POSIX/GNU command line argument parser.
|
||||
Arg_parser - POSIX/GNU command-line argument parser.
|
||||
Copyright (C) Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
|
|
|
|||
48
thirdparty/arg_parser/ChangeLog
vendored
48
thirdparty/arg_parser/ChangeLog
vendored
|
|
@ -1,3 +1,37 @@
|
|||
2026-03-10 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.21 released.
|
||||
* Replace 'bool in_order' with 'int flags'.
|
||||
* New flags 'in_order_stop' and 'in_order_skip'.
|
||||
* New flag 'neg_non_opt'. (Suggested by Mohammad Akhlaghi).
|
||||
* Rename Has_arg value 'yme' to 'yesme'.
|
||||
* carg_parser.h (struct Arg_parser): Remove 'error_size'.
|
||||
* carg_parser.c: Replace 'add_error' with 'set_error'.
|
||||
Add 'push_back_option', 'push_back_argument', and 'set_argument'.
|
||||
* arg_parser.texi: New section 'Differences with getopt_long'.
|
||||
* New files testsuite/test[1-4].txt.
|
||||
|
||||
2025-06-29 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.20 released.
|
||||
* main.cc, cmain.c: Refactor code to match examples in manual.
|
||||
* arg_parser.texi: New chapters 'Tutorial for the C++ version' and
|
||||
'Tutorial for the C version'. (Suggested by Mark Galassi).
|
||||
|
||||
2025-01-11 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.19 released.
|
||||
* New value in Has_arg; yme = 'yes but maybe empty'.
|
||||
* carg_parser.h: Use 'typedef' (again) in C version.
|
||||
* arg_parser.texi (Argument syntax): Document opts with empty argument.
|
||||
* check.sh: Use 'cp' instead of 'cat'.
|
||||
|
||||
2024-01-20 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.18 released.
|
||||
* arg_parser.texi (Argument syntax): Reorder, improve descriptions.
|
||||
* configure, Makefile.in: New variable 'MAKEINFO'.
|
||||
|
||||
2022-02-05 Antonio Diaz Diaz <antonio@gnu.org>
|
||||
|
||||
* Version 1.17 released.
|
||||
|
|
@ -75,14 +109,13 @@
|
|||
|
||||
* Version 1.5 released.
|
||||
* Minor fixes.
|
||||
* C version: C99 style comments '//' have been converted to C89
|
||||
style comments '/* */'.
|
||||
* C version: Convert C99 style comments '//' to C89 style '/* */'.
|
||||
* New files testsuite/check.sh, testsuite/test.txt.
|
||||
|
||||
2010-03-11 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 1.4 released.
|
||||
* carg_parser.h: Remove 'typedefs' from C version.
|
||||
* carg_parser.h: Remove 'typedef' from C version.
|
||||
* Add link exception to license.
|
||||
* The manual has been improved.
|
||||
* Makefile.in: Add option '--name' to help2man invocation.
|
||||
|
|
@ -112,15 +145,14 @@
|
|||
2006-11-04 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.2 released.
|
||||
* Some fixes made to 'configure' script.
|
||||
* configure: Some fixes.
|
||||
|
||||
2006-03-29 Antonio Diaz Diaz <ant_diaz@teleline.es>
|
||||
|
||||
* Version 0.1 released.
|
||||
|
||||
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This file is a collection of facts, and thus it is not copyrightable,
|
||||
but just in case, you have unlimited permission to copy, distribute, and
|
||||
modify it.
|
||||
This file is a collection of facts, and thus it is not copyrightable, but just
|
||||
in case, you have unlimited permission to copy, distribute, and modify it.
|
||||
|
|
|
|||
16
thirdparty/arg_parser/INSTALL
vendored
16
thirdparty/arg_parser/INSTALL
vendored
|
|
@ -4,7 +4,8 @@ You will need a C++98 compiler and a C89 compiler.
|
|||
(gcc 3.3.6 or newer is recommended).
|
||||
I use gcc 6.1.0 and 3.3.6, but the code should compile with any standards
|
||||
compliant compiler.
|
||||
Gcc is available at http://gcc.gnu.org.
|
||||
Gcc is available at http://gcc.gnu.org
|
||||
Lzip is available at http://www.nongnu.org/lzip/lzip.html
|
||||
|
||||
|
||||
Procedure
|
||||
|
|
@ -15,8 +16,8 @@ Procedure
|
|||
or
|
||||
lzip -cd arg_parser[version].tar.lz | tar -xf -
|
||||
|
||||
This creates the directory ./arg_parser[version] containing the source from
|
||||
the main archive.
|
||||
This creates the directory ./arg_parser[version] containing the source code
|
||||
extracted from the archive.
|
||||
|
||||
2. Change to arg_parser directory and run configure.
|
||||
(Try 'configure --help' for usage instructions).
|
||||
|
|
@ -31,7 +32,8 @@ the main archive.
|
|||
4. Optionally, type 'make check' to run the tests that come with arg_parser.
|
||||
|
||||
5. Type 'make install' to install the program and any data files and
|
||||
documentation.
|
||||
documentation. You need root privileges to install into a prefix owned
|
||||
by root.
|
||||
|
||||
Or type 'make install-compress', which additionally compresses the
|
||||
info manual and the man page after installation.
|
||||
|
|
@ -51,15 +53,15 @@ object files and executables to go and run the 'configure' script.
|
|||
'configure' automatically checks for the source code in '.', in '..', and
|
||||
in the directory that 'configure' is in.
|
||||
|
||||
'configure' recognizes the option '--srcdir=DIR' to control where to
|
||||
look for the sources. Usually 'configure' can determine that directory
|
||||
'configure' recognizes the option '--srcdir=DIR' to control where to look
|
||||
for the source code. Usually 'configure' can determine that directory
|
||||
automatically.
|
||||
|
||||
After running 'configure', you can run 'make' and 'make install' as
|
||||
explained above.
|
||||
|
||||
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
|
|
|||
15
thirdparty/arg_parser/Makefile.in
vendored
15
thirdparty/arg_parser/Makefile.in
vendored
|
|
@ -2,8 +2,8 @@
|
|||
DISTNAME = $(pkgname)-$(pkgversion)
|
||||
INSTALL = install
|
||||
INSTALL_PROGRAM = $(INSTALL) -m 755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
INSTALL_DIR = $(INSTALL) -d -m 755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
SHELL = /bin/sh
|
||||
CAN_RUN_INSTALLINFO = $(SHELL) -c "install-info --version" > /dev/null 2>&1
|
||||
|
||||
|
|
@ -37,16 +37,20 @@ arg_parser.o : arg_parser.cc
|
|||
carg_parser.o : carg_parser.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
# prevent 'make' from trying to remake source files
|
||||
$(VPATH)/configure $(VPATH)/Makefile.in $(VPATH)/doc/$(pkgname).texi : ;
|
||||
MAKEFLAGS += -r
|
||||
.SUFFIXES :
|
||||
|
||||
$(objs) : Makefile arg_parser.h
|
||||
$(cobjs) : Makefile carg_parser.h
|
||||
|
||||
|
||||
doc : info man
|
||||
|
||||
info : $(VPATH)/doc/$(pkgname).info
|
||||
|
||||
$(VPATH)/doc/$(pkgname).info : $(VPATH)/doc/$(pkgname).texi
|
||||
cd $(VPATH)/doc && makeinfo $(pkgname).texi
|
||||
cd $(VPATH)/doc && $(MAKEINFO) $(pkgname).texi
|
||||
|
||||
man : $(VPATH)/doc/$(progname).1 $(VPATH)/doc/c$(progname).1
|
||||
|
||||
|
|
@ -54,7 +58,8 @@ $(VPATH)/doc/$(progname).1 : $(progname)
|
|||
help2man -n 'test program for Arg_parser' -o $@ ./$(progname)
|
||||
|
||||
$(VPATH)/doc/c$(progname).1 : c$(progname)
|
||||
help2man -n 'test program for Arg_parser' -o $@ --info-page=$(pkgname) ./c$(progname)
|
||||
help2man -n 'test program for Arg_parser' \
|
||||
-o $@ --info-page=$(pkgname) ./c$(progname)
|
||||
|
||||
Makefile : $(VPATH)/configure $(VPATH)/Makefile.in
|
||||
./config.status
|
||||
|
|
@ -132,7 +137,7 @@ dist : doc
|
|||
$(DISTNAME)/*.c \
|
||||
$(DISTNAME)/*.cc \
|
||||
$(DISTNAME)/testsuite/check.sh \
|
||||
$(DISTNAME)/testsuite/test.txt
|
||||
$(DISTNAME)/testsuite/test[1-4].txt
|
||||
rm -f $(DISTNAME)
|
||||
lzip -v -9 $(DISTNAME).tar
|
||||
|
||||
|
|
|
|||
44
thirdparty/arg_parser/NEWS
vendored
44
thirdparty/arg_parser/NEWS
vendored
|
|
@ -1,5 +1,41 @@
|
|||
Changes in version 1.17:
|
||||
Changes in version 1.21:
|
||||
|
||||
The new functions 'parsed_name' (C++) and 'ap_parsed_name' (C) have been
|
||||
added. They return the full name of the option parsed (short or long) to
|
||||
help produce more accurate diagnostic messages.
|
||||
The last argument of the C++ constructor and of the C function 'ap_init' has
|
||||
been changed from 'bool in_order' to 'int flags'. This change is
|
||||
backwards-compatible after recompilation because the default value of both
|
||||
arguments is 0, and the new flag 'in_order' has a value of 1. So the old
|
||||
'in_order = true' is equivalent to the new 'flags = in_order'.
|
||||
|
||||
The C++ constructor and the C function 'ap_init' have been extended with the
|
||||
flag 'in_order_stop' to parse the first non-option argument and all the
|
||||
arguments following it as non-option arguments, even if they begin with a
|
||||
hyphen. This is similar to the POSIX function 'getopt', which stops option
|
||||
processing after finding the first non-option argument.
|
||||
|
||||
The C++ constructor and the C function 'ap_init' have been extended with the
|
||||
flag 'in_order_skip' to parse only the heading options, skipping the first
|
||||
non-option argument and all the arguments following it. This mode is useful
|
||||
for parsing the command line of programs that invoke other programs, like
|
||||
'timeout', 'xargs', or 'valgrind'.
|
||||
|
||||
The C++ constructor and the C function 'ap_init' have been extended with the
|
||||
flag 'neg_non_opt' to parse negative numbers as non-option arguments without
|
||||
reordering them. This mode is useful for parsing the command line of tools
|
||||
like 'seq' which take negative numbers as arguments. (Suggested by Mohammad
|
||||
Akhlaghi):
|
||||
|
||||
$ arg_parser +15 -Inf 0 -20 -a -.5 -v
|
||||
option '-a'
|
||||
option '-v'
|
||||
non-option argument '+15'
|
||||
non-option argument '-Inf'
|
||||
non-option argument '0'
|
||||
non-option argument '-20'
|
||||
non-option argument '-.5'
|
||||
|
||||
The 'enum Has_arg' value 'yme' has been renamed to 'yesme'.
|
||||
|
||||
The code of the C version has been reorganized.
|
||||
|
||||
The new section 'Differences with getopt and getopt_long' has been added to
|
||||
the manual.
|
||||
|
|
|
|||
31
thirdparty/arg_parser/README
vendored
31
thirdparty/arg_parser/README
vendored
|
|
@ -1,25 +1,31 @@
|
|||
Description
|
||||
|
||||
Arg_parser is an argument parser that follows POSIX and GNU conventions for
|
||||
command line arguments. There exist C++ and C versions of Arg_parser. The
|
||||
command-line arguments. There exist C++ and C versions of Arg_parser. The
|
||||
C++ version is implemented as a C++ class, while the C version is
|
||||
implemented as a single struct plus associated functions. Both are simpler,
|
||||
easier to use, and safer than 'getopt_long'.
|
||||
|
||||
For maximum stability, Arg_parser is self-contained. It extracts all the
|
||||
information it needs from its arguments to avoid refering to them later.
|
||||
This avoids index-out-of-bounds errors.
|
||||
information it needs from its arguments to avoid referring to them later.
|
||||
This avoids index-out-of-bounds errors and allows the parser object to be
|
||||
passed as argument to other functions for further analysis.
|
||||
|
||||
Arg_parser does not modify its arguments, nor uses any global variables. So
|
||||
you may create more than one parser in your program if you need or want to.
|
||||
Arg_parser does not modify its arguments (argc, argv), nor uses any global
|
||||
variables.
|
||||
|
||||
The C++ version of Arg_parser can also parse options from configuration
|
||||
files.
|
||||
|
||||
To use Arg_parser in your own programs simply copy the files 'arg_parser.h'
|
||||
and 'arg_parser.cc' (or 'carg_parser.h' and 'carg_parser.c' for the
|
||||
C version) in your source tree. See the file 'main.cc' ('cmain.c') for an
|
||||
example of use.
|
||||
The C++ version of Arg_parser is provided in the files 'arg_parser.h' and
|
||||
'arg_parser.cc'. To learn how to use Arg_parser in your C++ programs, see
|
||||
the C++ example in the manual and the example file 'main.cc' in the source
|
||||
tarball.
|
||||
|
||||
The C version of Arg_parser is provided in the files 'carg_parser.h' and
|
||||
'carg_parser.c'. To learn how to use Arg_parser in your C programs, see the
|
||||
C example in the manual and the example file 'cmain.c' in the source
|
||||
tarball.
|
||||
|
||||
Arg_parser was developed as the argument parser for GNU moe, because moe's
|
||||
argument parsing is rather complex. Then I used it in my other projects,
|
||||
|
|
@ -27,11 +33,10 @@ including GNU ddrescue, GNU ed, lzip, GNU ocrad, tarlz, and zutils, with
|
|||
excellent results.
|
||||
|
||||
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This file is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
||||
The file Makefile.in is a data file used by configure to produce the
|
||||
Makefile. It has the same copyright owner and permissions that configure
|
||||
itself.
|
||||
The file Makefile.in is a data file used by configure to produce the Makefile.
|
||||
It has the same copyright owner and permissions that configure itself.
|
||||
|
|
|
|||
49
thirdparty/arg_parser/arg_parser.cc
vendored
49
thirdparty/arg_parser/arg_parser.cc
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
|
@ -17,12 +17,24 @@
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "arg_parser.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool is_number( const char * const p )
|
||||
{
|
||||
return std::isdigit( (unsigned char)(p[*p=='.']) ) ||
|
||||
std::strcmp( p, "inf" ) == 0 || std::strcmp( p, "Inf" ) == 0 ||
|
||||
std::strcmp( p, "INF" ) == 0;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
|
||||
bool Arg_parser::parse_long_option( const char * const opt, const char * const arg,
|
||||
const Option options[], int & argind )
|
||||
|
|
@ -75,19 +87,19 @@ bool Arg_parser::parse_long_option( const char * const opt, const char * const a
|
|||
error_ += "' requires an argument";
|
||||
return false;
|
||||
}
|
||||
data.back().argument = &opt[len+3];
|
||||
data.back().argument = &opt[len+3]; // argument may be empty
|
||||
return true;
|
||||
}
|
||||
|
||||
if( options[index].has_arg == yes )
|
||||
if( options[index].has_arg == yes || options[index].has_arg == yesme )
|
||||
{
|
||||
if( !arg || !arg[0] )
|
||||
if( !arg || ( options[index].has_arg == yes && !arg[0] ) )
|
||||
{
|
||||
error_ = "option '--"; error_ += options[index].long_name;
|
||||
error_ += "' requires an argument";
|
||||
return false;
|
||||
}
|
||||
++argind; data.back().argument = arg;
|
||||
++argind; data.back().argument = arg; // argument may be empty
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -123,15 +135,16 @@ bool Arg_parser::parse_short_option( const char * const opt, const char * const
|
|||
{
|
||||
data.back().argument = &opt[cind]; ++argind; cind = 0;
|
||||
}
|
||||
else if( options[index].has_arg == yes )
|
||||
else if( options[index].has_arg == yes || options[index].has_arg == yesme )
|
||||
{
|
||||
if( !arg || !arg[0] )
|
||||
if( !arg || ( options[index].has_arg == yes && !arg[0] ) )
|
||||
{
|
||||
error_ = "option requires an argument -- '"; error_ += c;
|
||||
error_ += '\'';
|
||||
return false;
|
||||
}
|
||||
data.back().argument = arg; ++argind; cind = 0;
|
||||
++argind; cind = 0;
|
||||
data.back().argument = arg; // argument may be empty
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -139,7 +152,8 @@ bool Arg_parser::parse_short_option( const char * const opt, const char * const
|
|||
|
||||
|
||||
Arg_parser::Arg_parser( const int argc, const char * const argv[],
|
||||
const Option options[], const bool in_order )
|
||||
const Option options[], const int flags )
|
||||
: argv_index_( argc )
|
||||
{
|
||||
if( argc < 2 || !argv || !options ) return;
|
||||
|
||||
|
|
@ -151,9 +165,10 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
|
|||
const unsigned char ch1 = argv[argind][0];
|
||||
const unsigned char ch2 = ch1 ? argv[argind][1] : 0;
|
||||
|
||||
if( ch1 == '-' && ch2 ) // we found an option
|
||||
if( ch1 == '-' && ch2 && ( ch2 == '-' || (flags & neg_non_opt) == 0 ||
|
||||
!is_number( argv[argind] + 1 ) ) )
|
||||
{
|
||||
const char * const opt = argv[argind];
|
||||
const char * const opt = argv[argind]; // we found an option
|
||||
const char * const arg = ( argind + 1 < argc ) ? argv[argind+1] : 0;
|
||||
if( ch2 == '-' )
|
||||
{
|
||||
|
|
@ -162,14 +177,13 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
|
|||
}
|
||||
else if( !parse_short_option( opt, arg, options, argind ) ) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( in_order ) data.push_back( Record( argv[argind++] ) );
|
||||
else if( flags & (in_order_stop | in_order_skip) ) break;
|
||||
else if( flags & in_order ) data.push_back( Record( argv[argind++] ) );
|
||||
else non_options.push_back( argv[argind++] );
|
||||
}
|
||||
}
|
||||
if( !error_.empty() ) data.clear();
|
||||
else
|
||||
else if( flags & in_order_skip ) argv_index_ = argind;
|
||||
else // copy non-option arguments
|
||||
{
|
||||
for( unsigned i = 0; i < non_options.size(); ++i )
|
||||
data.push_back( Record( non_options[i] ) );
|
||||
|
|
@ -181,6 +195,7 @@ Arg_parser::Arg_parser( const int argc, const char * const argv[],
|
|||
|
||||
Arg_parser::Arg_parser( const char * const opt, const char * const arg,
|
||||
const Option options[] )
|
||||
: argv_index_( 0 )
|
||||
{
|
||||
if( !opt || !opt[0] || !options ) return;
|
||||
|
||||
|
|
|
|||
30
thirdparty/arg_parser/arg_parser.h
vendored
30
thirdparty/arg_parser/arg_parser.h
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C++ version)
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
|
@ -27,23 +27,29 @@
|
|||
option. A code value outside the unsigned char range means a long-only
|
||||
option.
|
||||
|
||||
Arg_parser normally makes it appear as if all the option arguments
|
||||
were specified before all the non-option arguments for the purposes
|
||||
of parsing, even if the user of your program intermixed option and
|
||||
non-option arguments. If you want the arguments in the exact order
|
||||
the user typed them, call 'Arg_parser' with 'in_order' = true.
|
||||
Arg_parser normally makes it appear as if all the options were specified
|
||||
before all the non-option arguments for the purposes of parsing, even if
|
||||
the user of your program intermixed options and non-option arguments. If
|
||||
you want the arguments in the exact order the user typed them, call
|
||||
'Arg_parser' with 'flags' = 'in_order'.
|
||||
|
||||
The argument '--' terminates all options; any following arguments are
|
||||
treated as non-option arguments, even if they begin with a hyphen.
|
||||
|
||||
The syntax for optional option arguments is '-<short_option><argument>'
|
||||
(without whitespace), or '--<long_option>=<argument>'.
|
||||
The syntax of options with an optional argument is
|
||||
'-<short_option><argument>' (without whitespace), or
|
||||
'--<long_option>=<argument>'.
|
||||
|
||||
The syntax of options with an empty argument is '-<short_option> ""',
|
||||
'--<long_option> ""', or '--<long_option>=""'.
|
||||
*/
|
||||
|
||||
class Arg_parser
|
||||
{
|
||||
public:
|
||||
enum Has_arg { no, yes, maybe };
|
||||
enum Flags { in_order = 1, in_order_stop = 2, in_order_skip = 4,
|
||||
neg_non_opt = 8 }; // negative is non-option
|
||||
enum Has_arg { no, yes, maybe, yesme }; // yesme = yes but maybe empty
|
||||
|
||||
struct Option
|
||||
{
|
||||
|
|
@ -68,6 +74,7 @@ private:
|
|||
const std::string empty_arg;
|
||||
std::string error_;
|
||||
std::vector< Record > data;
|
||||
int argv_index_;
|
||||
|
||||
bool parse_long_option( const char * const opt, const char * const arg,
|
||||
const Option options[], int & argind );
|
||||
|
|
@ -76,13 +83,14 @@ private:
|
|||
|
||||
public:
|
||||
Arg_parser( const int argc, const char * const argv[],
|
||||
const Option options[], const bool in_order = false );
|
||||
const Option options[], const int flags = 0 );
|
||||
|
||||
// Restricted constructor. Parses a single token and argument (if any).
|
||||
Arg_parser( const char * const opt, const char * const arg,
|
||||
const Option options[] );
|
||||
|
||||
const std::string & error() const { return error_; }
|
||||
int argv_index() const { return argv_index_; }
|
||||
|
||||
// The number of arguments parsed. May be different from argc.
|
||||
int arguments() const { return data.size(); }
|
||||
|
|
|
|||
223
thirdparty/arg_parser/carg_parser.c
vendored
223
thirdparty/arg_parser/carg_parser.c
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C version)
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
|
@ -17,12 +17,21 @@
|
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "carg_parser.h"
|
||||
|
||||
|
||||
static char is_number( const char * const p )
|
||||
{
|
||||
return isdigit( (unsigned char)(p[*p=='.']) ) ||
|
||||
strcmp( p, "inf" ) == 0 || strcmp( p, "Inf" ) == 0 ||
|
||||
strcmp( p, "INF" ) == 0;
|
||||
}
|
||||
|
||||
|
||||
/* assure at least a minimum size for buffer 'buf' */
|
||||
static void * ap_resize_buffer( void * buf, const int min_size )
|
||||
{
|
||||
|
|
@ -32,58 +41,78 @@ static void * ap_resize_buffer( void * buf, const int min_size )
|
|||
}
|
||||
|
||||
|
||||
static char push_back_record( struct Arg_parser * const ap, const int code,
|
||||
const char * const long_name,
|
||||
const char * const argument )
|
||||
static char set_argument( Arg_parser * const ap, const char * const argument )
|
||||
{
|
||||
struct ap_Record * p;
|
||||
void * tmp = ap_resize_buffer( ap->data,
|
||||
( ap->data_size + 1 ) * sizeof (struct ap_Record) );
|
||||
ap_Record * const p = &(ap->data[ap->data_size-1]);
|
||||
const int len = strlen( argument );
|
||||
p->argument = (char *)malloc( len + 1 );
|
||||
if( !p->argument ) return 0;
|
||||
memcpy( p->argument, argument, len + 1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static ap_Record * push_back_record( Arg_parser * const ap )
|
||||
{
|
||||
const int min_size = ( ap->data_size + 1 ) * sizeof (ap_Record);
|
||||
void * tmp = ap_resize_buffer( ap->data, min_size );
|
||||
if( !tmp ) return 0;
|
||||
ap->data = (struct ap_Record *)tmp;
|
||||
p = &(ap->data[ap->data_size]);
|
||||
ap->data = (ap_Record *)tmp;
|
||||
return &(ap->data[ap->data_size++]);
|
||||
}
|
||||
|
||||
|
||||
static char push_back_option( Arg_parser * const ap, const int code,
|
||||
const char * const long_name )
|
||||
{
|
||||
ap_Record * const p = push_back_record( ap );
|
||||
if( !p ) return 0;
|
||||
p->code = code;
|
||||
p->argument = 0;
|
||||
if( long_name )
|
||||
{
|
||||
const int len = strlen( long_name );
|
||||
p->parsed_name = (char *)malloc( len + 2 + 1 );
|
||||
if( !p->parsed_name ) return 0;
|
||||
p->parsed_name[0] = p->parsed_name[1] = '-';
|
||||
strncpy( p->parsed_name + 2, long_name, len + 1 );
|
||||
memcpy( p->parsed_name + 2, long_name, len + 1 );
|
||||
}
|
||||
else if( code > 0 && code < 256 )
|
||||
else
|
||||
{
|
||||
p->parsed_name = (char *)malloc( 2 + 1 );
|
||||
if( !p->parsed_name ) return 0;
|
||||
p->parsed_name[0] = '-'; p->parsed_name[1] = code; p->parsed_name[2] = 0;
|
||||
}
|
||||
else p->parsed_name = 0;
|
||||
if( argument )
|
||||
{
|
||||
const int len = strlen( argument );
|
||||
p->argument = (char *)malloc( len + 1 );
|
||||
if( !p->argument ) { free( p->parsed_name ); return 0; }
|
||||
strncpy( p->argument, argument, len + 1 );
|
||||
}
|
||||
else p->argument = 0;
|
||||
++ap->data_size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static char add_error( struct Arg_parser * const ap, const char * const msg )
|
||||
static char push_back_argument( Arg_parser * const ap,
|
||||
const char * const argument )
|
||||
{
|
||||
const int len = strlen( msg );
|
||||
void * tmp = ap_resize_buffer( ap->error, ap->error_size + len + 1 );
|
||||
ap_Record * const p = push_back_record( ap );
|
||||
if( !p ) return 0;
|
||||
p->code = 0;
|
||||
p->parsed_name = 0;
|
||||
return set_argument( ap, argument );
|
||||
}
|
||||
|
||||
|
||||
static char set_error( Arg_parser * const ap, const char * const s1,
|
||||
const char * const s2, const char * const s3 )
|
||||
{
|
||||
const int l1 = strlen( s1 ), l2 = strlen( s2 ), l3 = strlen( s3 );
|
||||
void * tmp = ap_resize_buffer( ap->error, l1 + l2 + l3 + 1 );
|
||||
if( !tmp ) return 0;
|
||||
ap->error = (char *)tmp;
|
||||
strncpy( ap->error + ap->error_size, msg, len + 1 );
|
||||
ap->error_size += len;
|
||||
memcpy( ap->error, s1, l1 );
|
||||
memcpy( ap->error + l1, s2, l2 );
|
||||
memcpy( ap->error + l1 + l2, s3, l3 + 1 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void free_data( struct Arg_parser * const ap )
|
||||
static void free_data( Arg_parser * const ap )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < ap->data_size; ++i )
|
||||
|
|
@ -94,10 +123,9 @@ static void free_data( struct Arg_parser * const ap )
|
|||
|
||||
|
||||
/* Return 0 only if out of memory. */
|
||||
static char parse_long_option( struct Arg_parser * const ap,
|
||||
static char parse_long_option( Arg_parser * const ap,
|
||||
const char * const opt, const char * const arg,
|
||||
const struct ap_Option options[],
|
||||
int * const argindp )
|
||||
const ap_Option options[], int * const argindp )
|
||||
{
|
||||
unsigned len;
|
||||
int index = -1, i;
|
||||
|
|
@ -119,62 +147,43 @@ static char parse_long_option( struct Arg_parser * const ap,
|
|||
}
|
||||
|
||||
if( ambig && !exact )
|
||||
{
|
||||
add_error( ap, "option '" ); add_error( ap, opt );
|
||||
add_error( ap, "' is ambiguous" );
|
||||
return 1;
|
||||
}
|
||||
return set_error( ap, "option '", opt, "' is ambiguous" );
|
||||
|
||||
if( index < 0 ) /* nothing found */
|
||||
{
|
||||
add_error( ap, "unrecognized option '" ); add_error( ap, opt );
|
||||
add_error( ap, "'" );
|
||||
return 1;
|
||||
}
|
||||
return set_error( ap, "unrecognized option '", opt, "'" );
|
||||
|
||||
++*argindp;
|
||||
if( !push_back_option( ap, options[index].code, options[index].long_name ) )
|
||||
return 0;
|
||||
|
||||
if( opt[len+2] ) /* '--<long_option>=<argument>' syntax */
|
||||
{
|
||||
if( options[index].has_arg == ap_no )
|
||||
{
|
||||
add_error( ap, "option '--" ); add_error( ap, options[index].long_name );
|
||||
add_error( ap, "' doesn't allow an argument" );
|
||||
return 1;
|
||||
}
|
||||
return set_error( ap, "option '--", options[index].long_name,
|
||||
"' doesn't allow an argument" );
|
||||
if( options[index].has_arg == ap_yes && !opt[len+3] )
|
||||
{
|
||||
add_error( ap, "option '--" ); add_error( ap, options[index].long_name );
|
||||
add_error( ap, "' requires an argument" );
|
||||
return 1;
|
||||
}
|
||||
return push_back_record( ap, options[index].code,
|
||||
options[index].long_name, &opt[len+3] );
|
||||
return set_error( ap, "option '--", options[index].long_name,
|
||||
"' requires an argument" );
|
||||
return set_argument( ap, &opt[len+3] ); /* argument may be empty */
|
||||
}
|
||||
|
||||
if( options[index].has_arg == ap_yes )
|
||||
if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yesme )
|
||||
{
|
||||
if( !arg || !arg[0] )
|
||||
{
|
||||
add_error( ap, "option '--" ); add_error( ap, options[index].long_name );
|
||||
add_error( ap, "' requires an argument" );
|
||||
return 1;
|
||||
}
|
||||
if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) )
|
||||
return set_error( ap, "option '--", options[index].long_name,
|
||||
"' requires an argument" );
|
||||
++*argindp;
|
||||
return push_back_record( ap, options[index].code,
|
||||
options[index].long_name, arg );
|
||||
return set_argument( ap, arg ); /* argument may be empty */
|
||||
}
|
||||
|
||||
return push_back_record( ap, options[index].code,
|
||||
options[index].long_name, 0 );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Return 0 only if out of memory. */
|
||||
static char parse_short_option( struct Arg_parser * const ap,
|
||||
static char parse_short_option( Arg_parser * const ap,
|
||||
const char * const opt, const char * const arg,
|
||||
const struct ap_Option options[],
|
||||
int * const argindp )
|
||||
const ap_Option options[], int * const argindp )
|
||||
{
|
||||
int cind = 1; /* character index in opt */
|
||||
|
||||
|
|
@ -191,49 +200,42 @@ static char parse_short_option( struct Arg_parser * const ap,
|
|||
{ index = i; break; }
|
||||
|
||||
if( index < 0 )
|
||||
{
|
||||
add_error( ap, "invalid option -- '" ); add_error( ap, code_str );
|
||||
add_error( ap, "'" );
|
||||
return 1;
|
||||
}
|
||||
return set_error( ap, "invalid option -- '", code_str, "'" );
|
||||
|
||||
if( !push_back_option( ap, c, 0 ) ) return 0;
|
||||
if( opt[++cind] == 0 ) { ++*argindp; cind = 0; } /* opt finished */
|
||||
|
||||
if( options[index].has_arg != ap_no && cind > 0 && opt[cind] )
|
||||
{
|
||||
if( !push_back_record( ap, c, 0, &opt[cind] ) ) return 0;
|
||||
if( !set_argument( ap, &opt[cind] ) ) return 0;
|
||||
++*argindp; cind = 0;
|
||||
}
|
||||
else if( options[index].has_arg == ap_yes )
|
||||
else if( options[index].has_arg == ap_yes || options[index].has_arg == ap_yesme )
|
||||
{
|
||||
if( !arg || !arg[0] )
|
||||
{
|
||||
add_error( ap, "option requires an argument -- '" );
|
||||
add_error( ap, code_str ); add_error( ap, "'" );
|
||||
return 1;
|
||||
}
|
||||
if( !arg || ( options[index].has_arg == ap_yes && !arg[0] ) )
|
||||
return set_error( ap, "option requires an argument -- '", code_str, "'" );
|
||||
++*argindp; cind = 0;
|
||||
if( !push_back_record( ap, c, 0, arg ) ) return 0;
|
||||
if( !set_argument( ap, arg ) ) return 0; /* argument may be empty */
|
||||
}
|
||||
else if( !push_back_record( ap, c, 0, 0 ) ) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
char ap_init( struct Arg_parser * const ap,
|
||||
/* Return 0 only if out of memory. */
|
||||
char ap_init( Arg_parser * const ap,
|
||||
const int argc, const char * const argv[],
|
||||
const struct ap_Option options[], const char in_order )
|
||||
const ap_Option options[], const int flags )
|
||||
{
|
||||
const char ** non_options = 0; /* skipped non-options */
|
||||
int non_options_size = 0; /* number of skipped non-options */
|
||||
int argind = 1; /* index in argv */
|
||||
char done = 0; /* false until success */
|
||||
char done = 0; /* false until success or error */
|
||||
|
||||
ap->data = 0;
|
||||
ap->error = 0;
|
||||
ap->data_size = 0;
|
||||
ap->error_size = 0;
|
||||
ap->argv_index = argc;
|
||||
if( argc < 2 || !argv || !options ) return 1;
|
||||
|
||||
while( argind < argc )
|
||||
|
|
@ -241,78 +243,75 @@ char ap_init( struct Arg_parser * const ap,
|
|||
const unsigned char ch1 = argv[argind][0];
|
||||
const unsigned char ch2 = ch1 ? argv[argind][1] : 0;
|
||||
|
||||
if( ch1 == '-' && ch2 ) /* we found an option */
|
||||
if( ch1 == '-' && ch2 && ( ch2 == '-' || (flags & ap_neg_non_opt) == 0 ||
|
||||
!is_number( argv[argind] + 1 ) ) )
|
||||
{
|
||||
const char * const opt = argv[argind];
|
||||
const char * const opt = argv[argind]; /* we found an option */
|
||||
const char * const arg = ( argind + 1 < argc ) ? argv[argind+1] : 0;
|
||||
if( ch2 == '-' )
|
||||
{
|
||||
if( !argv[argind][2] ) { ++argind; break; } /* we found "--" */
|
||||
else if( !parse_long_option( ap, opt, arg, options, &argind ) ) goto out;
|
||||
else if( !parse_long_option( ap, opt, arg, options, &argind ) ) goto oom;
|
||||
}
|
||||
else if( !parse_short_option( ap, opt, arg, options, &argind ) ) goto out;
|
||||
else if( !parse_short_option( ap, opt, arg, options, &argind ) ) goto oom;
|
||||
if( ap->error ) break;
|
||||
}
|
||||
else if( flags & (ap_in_order_stop | ap_in_order_skip) ) break;
|
||||
else if( flags & ap_in_order )
|
||||
{ if( !push_back_argument( ap, argv[argind++] ) ) goto oom; }
|
||||
else
|
||||
{
|
||||
if( in_order )
|
||||
{ if( !push_back_record( ap, 0, 0, argv[argind++] ) ) goto out; }
|
||||
else
|
||||
{
|
||||
void * tmp = ap_resize_buffer( non_options,
|
||||
( non_options_size + 1 ) * sizeof *non_options );
|
||||
if( !tmp ) goto out;
|
||||
const int min_size = ( non_options_size + 1 ) * sizeof non_options[0];
|
||||
void * tmp = ap_resize_buffer( non_options, min_size );
|
||||
if( !tmp ) goto oom;
|
||||
non_options = (const char **)tmp;
|
||||
non_options[non_options_size++] = argv[argind++];
|
||||
}
|
||||
}
|
||||
}
|
||||
if( ap->error ) free_data( ap );
|
||||
else
|
||||
else if( flags & ap_in_order_skip ) ap->argv_index = argind;
|
||||
else /* copy non-option arguments */
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < non_options_size; ++i )
|
||||
if( !push_back_record( ap, 0, 0, non_options[i] ) ) goto out;
|
||||
if( !push_back_argument( ap, non_options[i] ) ) goto oom;
|
||||
while( argind < argc )
|
||||
if( !push_back_record( ap, 0, 0, argv[argind++] ) ) goto out;
|
||||
if( !push_back_argument( ap, argv[argind++] ) ) goto oom;
|
||||
}
|
||||
done = 1;
|
||||
out: if( non_options ) free( non_options );
|
||||
oom: if( non_options ) free( non_options );
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
void ap_free( struct Arg_parser * const ap )
|
||||
void ap_free( Arg_parser * const ap )
|
||||
{
|
||||
free_data( ap );
|
||||
if( ap->error ) { free( ap->error ); ap->error = 0; }
|
||||
ap->error_size = 0;
|
||||
}
|
||||
|
||||
|
||||
const char * ap_error( const struct Arg_parser * const ap )
|
||||
{ return ap->error; }
|
||||
const char * ap_error( const Arg_parser * const ap ) { return ap->error; }
|
||||
|
||||
int ap_argv_index( const Arg_parser * const ap ) { return ap->argv_index; }
|
||||
|
||||
int ap_arguments( const struct Arg_parser * const ap )
|
||||
{ return ap->data_size; }
|
||||
int ap_arguments( const Arg_parser * const ap ) { return ap->data_size; }
|
||||
|
||||
|
||||
int ap_code( const struct Arg_parser * const ap, const int i )
|
||||
int ap_code( const Arg_parser * const ap, const int i )
|
||||
{
|
||||
if( i < 0 || i >= ap_arguments( ap ) ) return 0;
|
||||
return ap->data[i].code;
|
||||
}
|
||||
|
||||
|
||||
const char * ap_parsed_name( const struct Arg_parser * const ap, const int i )
|
||||
const char * ap_parsed_name( const Arg_parser * const ap, const int i )
|
||||
{
|
||||
if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].parsed_name ) return "";
|
||||
return ap->data[i].parsed_name;
|
||||
}
|
||||
|
||||
|
||||
const char * ap_argument( const struct Arg_parser * const ap, const int i )
|
||||
const char * ap_argument( const Arg_parser * const ap, const int i )
|
||||
{
|
||||
if( i < 0 || i >= ap_arguments( ap ) || !ap->data[i].argument ) return "";
|
||||
return ap->data[i].argument;
|
||||
|
|
|
|||
66
thirdparty/arg_parser/carg_parser.h
vendored
66
thirdparty/arg_parser/carg_parser.h
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C version)
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This library is free software. Redistribution and use in source and
|
||||
binary forms, with or without modification, are permitted provided
|
||||
|
|
@ -20,77 +20,85 @@
|
|||
/* Arg_parser reads the arguments in 'argv' and creates a number of
|
||||
option codes, option arguments, and non-option arguments.
|
||||
|
||||
In case of error, 'ap_error' returns a non-null pointer to an error
|
||||
message.
|
||||
In case of error, 'ap_error' returns a pointer to an error message.
|
||||
|
||||
'options' is an array of 'struct ap_Option' terminated by an element
|
||||
containing a code which is zero. A null long_name means a short-only
|
||||
option. A code value outside the unsigned char range means a long-only
|
||||
option.
|
||||
|
||||
Arg_parser normally makes it appear as if all the option arguments
|
||||
were specified before all the non-option arguments for the purposes
|
||||
of parsing, even if the user of your program intermixed option and
|
||||
non-option arguments. If you want the arguments in the exact order
|
||||
the user typed them, call 'ap_init' with 'in_order' = true.
|
||||
Arg_parser normally makes it appear as if all the options were specified
|
||||
before all the non-option arguments for the purposes of parsing, even if
|
||||
the user of your program intermixed options and non-option arguments. If
|
||||
you want the arguments in the exact order the user typed them, call
|
||||
'ap_init' with 'flags' = 'ap_in_order'.
|
||||
|
||||
The argument '--' terminates all options; any following arguments are
|
||||
treated as non-option arguments, even if they begin with a hyphen.
|
||||
|
||||
The syntax for optional option arguments is '-<short_option><argument>'
|
||||
(without whitespace), or '--<long_option>=<argument>'.
|
||||
The syntax of options with an optional argument is
|
||||
'-<short_option><argument>' (without whitespace), or
|
||||
'--<long_option>=<argument>'.
|
||||
|
||||
The syntax of options with an empty argument is '-<short_option> ""',
|
||||
'--<long_option> ""', or '--<long_option>=""'.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum ap_Has_arg { ap_no, ap_yes, ap_maybe };
|
||||
enum ap_Flags { ap_in_order = 1, ap_in_order_stop = 2, ap_in_order_skip = 4,
|
||||
ap_neg_non_opt = 8 }; /* negative is non-option */
|
||||
/* ap_yesme = yes but maybe empty */
|
||||
typedef enum ap_Has_arg { ap_no, ap_yes, ap_maybe, ap_yesme } ap_Has_arg;
|
||||
|
||||
struct ap_Option
|
||||
typedef struct ap_Option
|
||||
{
|
||||
int code; /* Short option letter or code ( code != 0 ) */
|
||||
const char * long_name; /* Long option name (maybe null) */
|
||||
enum ap_Has_arg has_arg;
|
||||
};
|
||||
ap_Has_arg has_arg;
|
||||
} ap_Option;
|
||||
|
||||
|
||||
struct ap_Record
|
||||
typedef struct ap_Record
|
||||
{
|
||||
int code;
|
||||
char * parsed_name;
|
||||
char * argument;
|
||||
};
|
||||
} ap_Record;
|
||||
|
||||
|
||||
struct Arg_parser
|
||||
typedef struct Arg_parser
|
||||
{
|
||||
struct ap_Record * data;
|
||||
ap_Record * data;
|
||||
char * error;
|
||||
int data_size;
|
||||
int error_size;
|
||||
};
|
||||
int argv_index;
|
||||
} Arg_parser;
|
||||
|
||||
|
||||
char ap_init( struct Arg_parser * const ap,
|
||||
/* Return 0 only if out of memory. */
|
||||
char ap_init( Arg_parser * const ap,
|
||||
const int argc, const char * const argv[],
|
||||
const struct ap_Option options[], const char in_order );
|
||||
const ap_Option options[], const int flags );
|
||||
|
||||
void ap_free( struct Arg_parser * const ap );
|
||||
void ap_free( Arg_parser * const ap );
|
||||
|
||||
const char * ap_error( const struct Arg_parser * const ap );
|
||||
const char * ap_error( const Arg_parser * const ap );
|
||||
int ap_argv_index( const Arg_parser * const ap );
|
||||
|
||||
/* The number of arguments parsed. May be different from argc. */
|
||||
int ap_arguments( const struct Arg_parser * const ap );
|
||||
int ap_arguments( const Arg_parser * const ap );
|
||||
|
||||
/* If ap_code( i ) is 0, ap_argument( i ) is a non-option.
|
||||
Else ap_argument( i ) is the option's argument (or empty). */
|
||||
int ap_code( const struct Arg_parser * const ap, const int i );
|
||||
int ap_code( const Arg_parser * const ap, const int i );
|
||||
|
||||
/* Full name of the option parsed (short or long). */
|
||||
const char * ap_parsed_name( const struct Arg_parser * const ap, const int i );
|
||||
const char * ap_parsed_name( const Arg_parser * const ap, const int i );
|
||||
|
||||
const char * ap_argument( const struct Arg_parser * const ap, const int i );
|
||||
const char * ap_argument( const Arg_parser * const ap, const int i );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
189
thirdparty/arg_parser/cmain.c
vendored
189
thirdparty/arg_parser/cmain.c
vendored
|
|
@ -1,5 +1,5 @@
|
|||
/* Arg_parser - POSIX/GNU command line argument parser. (C version)
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
/* Arg_parser - POSIX/GNU command-line argument parser. (C version)
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This program is free software: you have unlimited permission to
|
||||
copy, distribute, and modify it.
|
||||
|
|
@ -10,9 +10,9 @@
|
|||
*/
|
||||
/*
|
||||
Exit status: 0 for a normal exit, 1 for environmental problems
|
||||
(file not found, invalid flags, I/O errors, etc), 2 to indicate a
|
||||
corrupt or invalid input file, 3 for an internal consistency error
|
||||
(e.g., bug) which caused carg_parser to panic.
|
||||
(file not found, invalid command-line options, I/O errors, etc), 2 to
|
||||
indicate a corrupt or invalid input file, 3 for an internal consistency
|
||||
error (e.g., bug) which caused carg_parser to panic.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
|
@ -24,54 +24,61 @@
|
|||
|
||||
|
||||
static const char * const program_name = "carg_parser";
|
||||
static const char * const program_year = "2022";
|
||||
static const char * const program_year = "2026";
|
||||
static const char * invocation_name = "carg_parser"; /* default value */
|
||||
static unsigned verbosity = 0;
|
||||
enum { opt_lo = 256 };
|
||||
|
||||
|
||||
static void show_help( const char verbose )
|
||||
static void show_help( void )
|
||||
{
|
||||
printf( "Arg_parser - POSIX/GNU command line argument parser. (C version)\n"
|
||||
fputs(
|
||||
"Arg_parser - POSIX/GNU command-line argument parser. (C version)\n"
|
||||
"\nArg_parser is an argument parser that follows POSIX and GNU conventions for\n"
|
||||
"command line arguments. There exist C++ and C versions of Arg_parser. The\n"
|
||||
"command-line arguments. There exist C++ and C versions of Arg_parser. The\n"
|
||||
"C++ version is implemented as a C++ class, while the C version is\n"
|
||||
"implemented as a single struct plus associated functions. Both are simpler,\n"
|
||||
"easier to use, and safer than 'getopt_long'.\n"
|
||||
"\nFor maximum stability, Arg_parser is self-contained. It extracts all the\n"
|
||||
"information it needs from its arguments to avoid refering to them later.\n"
|
||||
"This avoids index-out-of-bounds errors.\n"
|
||||
"\nArg_parser does not modify its arguments, nor uses any global variables. So\n"
|
||||
"you may create more than one parser in your program if you need or want to.\n"
|
||||
"information it needs from its arguments to avoid referring to them later.\n"
|
||||
"This avoids index-out-of-bounds errors and allows the parser object to be\n"
|
||||
"passed as argument to other functions for further analysis.\n"
|
||||
"\nArg_parser does not modify its arguments (argc, argv), nor uses any global\n"
|
||||
"variables.\n"
|
||||
"\nThe C++ version of Arg_parser can also parse options from configuration\n"
|
||||
"files.\n"
|
||||
"\nTo use Arg_parser in your own programs simply copy the files 'carg_parser.h'\n"
|
||||
"and 'carg_parser.c' in your source tree. See the file 'cmain.c' for an\n"
|
||||
"example of use.\n"
|
||||
"\nUsage: %s [options]\n", invocation_name );
|
||||
printf( "\nOptions:\n"
|
||||
"\nThe C version of Arg_parser is provided in the files 'carg_parser.h' and\n"
|
||||
"'carg_parser.c'. To learn how to use Arg_parser in your C programs, see the\n"
|
||||
"C example in the manual and the example file 'cmain.c' in the source\n"
|
||||
"tarball.\n", stdout );
|
||||
printf( "\nUsage: %s [options]\n", invocation_name );
|
||||
fputs( "\nOptions:\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
" -V, --version output version information and exit\n"
|
||||
" -a, --append example of option with no argument\n"
|
||||
" -b, --block=<arg> example of option with required argument\n"
|
||||
" -c, --casual[=<arg>] example of option with optional argument\n"
|
||||
" -e, --empty=<arg> example of option with maybe empty argument\n"
|
||||
" -o <arg> example of short only option\n"
|
||||
" --orphan example of long only option\n"
|
||||
" --long-only example of long only option\n"
|
||||
" -q, --quiet quiet operation\n"
|
||||
" -u, --uncaught example of intentional bug\n"
|
||||
" -v, --verbose verbose operation\n" );
|
||||
if( verbose )
|
||||
printf( " -H, --hidden example of hidden option (shown with -v -h)\n" );
|
||||
printf( "\nReport bugs to arg-parser-bug@nongnu.org\n"
|
||||
"Arg_parser home page: http://www.nongnu.org/arg-parser/arg_parser.html\n" );
|
||||
" -v, --verbose verbose operation\n", stdout );
|
||||
if( verbosity ) fputs(
|
||||
" -H, --hidden example of hidden option (shown with -v -h)\n", stdout );
|
||||
fputs(
|
||||
"\nReport bugs to arg-parser-bug@nongnu.org\n"
|
||||
"Arg_parser home page: http://www.nongnu.org/arg-parser/arg_parser.html\n", stdout );
|
||||
}
|
||||
|
||||
|
||||
static void show_version()
|
||||
static void show_version( void )
|
||||
{
|
||||
printf( "%s %s\n", program_name, PROGVERSION );
|
||||
printf( "Copyright (C) %s Antonio Diaz Diaz.\n", program_year );
|
||||
printf( "License 2-clause BSD.\n"
|
||||
fputs( "License 2-clause BSD.\n"
|
||||
"This is free software: you are free to change and redistribute it.\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.\n" );
|
||||
"There is NO WARRANTY, to the extent permitted by law.\n", stdout );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -95,75 +102,121 @@ static void internal_error( const char * const msg )
|
|||
}
|
||||
|
||||
|
||||
static void print_opt( const char * const arg, const char * const option_name,
|
||||
const int code )
|
||||
{
|
||||
printf( "option '%s'", option_name );
|
||||
if( arg[0] || code == 'e' ) printf( " with argument '%s'", arg );
|
||||
if( code == INT_MIN || code == INT_MAX ) printf( " (code 0x%X)", code );
|
||||
fputc( '\n', stdout );
|
||||
}
|
||||
|
||||
|
||||
static char process_options( const Arg_parser * const parserp )
|
||||
{
|
||||
int argind;
|
||||
verbosity = 0;
|
||||
for( argind = 0; argind < ap_arguments( parserp ); ++argind )
|
||||
{
|
||||
const int code = ap_code( parserp, argind );
|
||||
const char * const pn = ap_parsed_name( parserp, argind );
|
||||
const char * const arg = ap_argument( parserp, argind );
|
||||
switch( code )
|
||||
{
|
||||
case 0: printf( "non-option argument '%s'\n", arg ); break;
|
||||
case '.': case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c':
|
||||
case 'e': print_opt( arg, pn, code ); break;
|
||||
case 'h': show_help(); return 0;
|
||||
case 'H': case 'i': case 'I':
|
||||
case 'o': print_opt( arg, pn, code ); break;
|
||||
case 'q': print_opt( arg, pn, code ); verbosity = 0; break;
|
||||
/* case 'u': break; */ /* intentionally not caught */
|
||||
case 'v': print_opt( arg, pn, code ); ++verbosity; break;
|
||||
case 'V': show_version(); return 0;
|
||||
case opt_lo:
|
||||
case INT_MIN: case INT_MAX: print_opt( arg, pn, code ); break;
|
||||
default: internal_error( "uncaught option." );
|
||||
}
|
||||
} /* end process arguments */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main( const int argc, const char * const argv[] )
|
||||
{
|
||||
char verbose = 0;
|
||||
const struct ap_Option options[] =
|
||||
const ap_Option options[] =
|
||||
{
|
||||
/* code, long_name, has_arg (no/yes/maybe/yesme) */
|
||||
{ '.', 0, ap_maybe },
|
||||
{ '0', 0, ap_maybe },
|
||||
{ '1', 0, ap_maybe },
|
||||
{ '2', 0, ap_maybe },
|
||||
{ '3', 0, ap_maybe },
|
||||
{ '4', 0, ap_maybe },
|
||||
{ '5', 0, ap_maybe },
|
||||
{ '6', 0, ap_maybe },
|
||||
{ '7', 0, ap_maybe },
|
||||
{ '8', 0, ap_maybe },
|
||||
{ '9', 0, ap_maybe },
|
||||
{ 'a', "append", ap_no },
|
||||
{ 'b', "block", ap_yes },
|
||||
{ 'c', "casual", ap_maybe },
|
||||
{ 'e', "empty", ap_yesme },
|
||||
{ 'h', "help", ap_no },
|
||||
{ 'H', "hidden", ap_no },
|
||||
{ 'i', 0, ap_maybe },
|
||||
{ 'I', 0, ap_maybe },
|
||||
{ 'o', 0, ap_yes },
|
||||
{ 'q', "quiet", ap_no },
|
||||
{ 'u', "uncaught", ap_no },
|
||||
{ 'v', "verbose", ap_no },
|
||||
{ 'V', "version", ap_no },
|
||||
{ 256, "orphan", ap_no },
|
||||
{ opt_lo, "long-only", ap_no },
|
||||
{ INT_MIN, "int-min", ap_no },
|
||||
{ INT_MAX, "int-max", ap_no },
|
||||
{ 0, 0, ap_no } };
|
||||
|
||||
struct Arg_parser parser;
|
||||
int argind;
|
||||
Arg_parser parser;
|
||||
int flags;
|
||||
if( argc > 0 ) invocation_name = argv[0];
|
||||
|
||||
if( !ap_init( &parser, argc, argv, options, 0 ) )
|
||||
{ show_error( "Not enough memory.", 0, 0 ); return 1; }
|
||||
if( ap_error( &parser ) ) /* bad option */
|
||||
{ show_error( ap_error( &parser ), 0, 1 ); return 1; }
|
||||
if( !process_options( &parser ) ) return 0;
|
||||
fputs( !ap_arguments( &parser ) ?
|
||||
"No arguments!\n" : "(options reordered)\n", stdout );
|
||||
if( verbosity ) fputc( '\n', stdout ); else return 0;
|
||||
|
||||
for( argind = 0; argind < ap_arguments( &parser ); ++argind )
|
||||
{
|
||||
const int code = ap_code( &parser, argind );
|
||||
if( !code ) break; /* no more options */
|
||||
switch( code )
|
||||
{
|
||||
case 'a': break; /* example, do nothing */
|
||||
case 'b': break; /* example, do nothing */
|
||||
case 'c': break; /* example, do nothing */
|
||||
case 'h': show_help( verbose ); return 0;
|
||||
case 'H': break; /* example, do nothing */
|
||||
case 'o': break; /* example, do nothing */
|
||||
case 'q': verbose = 0; break;
|
||||
/* case 'u': break; */ /* intentionally not caught */
|
||||
case 'v': verbose = 1; break;
|
||||
case 'V': show_version(); return 0;
|
||||
case 256: break; /* example, do nothing */
|
||||
case INT_MIN: break; /* example, do nothing */
|
||||
case INT_MAX: break; /* example, do nothing */
|
||||
default : internal_error( "uncaught option." );
|
||||
}
|
||||
} /* end process options */
|
||||
if( !ap_init( &parser, argc, argv, options, ap_neg_non_opt ) )
|
||||
{ show_error( "Not enough memory.", 0, 0 ); return 1; }
|
||||
if( ap_error( &parser ) ) /* bad option */
|
||||
{ show_error( ap_error( &parser ), 0, 1 ); return 1; }
|
||||
process_options( &parser );
|
||||
fputs( "(options reordered"
|
||||
" and negative numbers treated as non-options)\n", stdout );
|
||||
if( verbosity == 1 ) return 0;
|
||||
|
||||
for( argind = 0; argind < ap_arguments( &parser ); ++argind )
|
||||
for( flags = 1; flags < 16; ++flags )
|
||||
{
|
||||
const int code = ap_code( &parser, argind );
|
||||
const char * const arg = ap_argument( &parser, argind );
|
||||
if( code ) /* option */
|
||||
{
|
||||
printf( "option '%s'", ap_parsed_name( &parser, argind ) );
|
||||
if( arg[0] ) printf( " with argument '%s'", arg );
|
||||
if( code == INT_MIN || code == INT_MAX ) printf( " (code 0x%X)", code );
|
||||
}
|
||||
else /* non-option */
|
||||
printf( "non-option argument '%s'", arg );
|
||||
int i;
|
||||
if( flags == ap_neg_non_opt ) continue; /* done above */
|
||||
fputc( '\n', stdout );
|
||||
if( !ap_init( &parser, argc, argv, options, flags ) )
|
||||
{ show_error( "Not enough memory.", 0, 0 ); return 1; }
|
||||
if( ap_error( &parser ) ) /* bad option */
|
||||
{ show_error( ap_error( &parser ), 0, 1 ); return 1; }
|
||||
process_options( &parser );
|
||||
for( i = ap_argv_index( &parser ); i < argc; ++i )
|
||||
printf( "skipped non-option argument '%s'\n", argv[i] );
|
||||
printf( "(0%s%s%s%s)\n",
|
||||
(flags & ap_in_order) ? " | in_order" : "",
|
||||
(flags & ap_in_order_stop) ? " | in_order_stop" : "",
|
||||
(flags & ap_in_order_skip) ? " | in_order_skip" : "",
|
||||
(flags & ap_neg_non_opt) ? " | neg_non_opt" : "" );
|
||||
}
|
||||
|
||||
if( !ap_arguments( &parser ) ) fputs( "Hello, world!\n", stdout );
|
||||
|
||||
ap_free( &parser );
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
39
thirdparty/arg_parser/configure
vendored
39
thirdparty/arg_parser/configure
vendored
|
|
@ -1,12 +1,12 @@
|
|||
#! /bin/sh
|
||||
# configure script for Arg_parser - POSIX/GNU command line argument parser.
|
||||
# Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
# configure script for Arg_parser - POSIX/GNU command-line argument parser.
|
||||
# Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
#
|
||||
# This configure script is free software: you have unlimited permission
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
pkgname=arg_parser
|
||||
pkgversion=1.17
|
||||
pkgversion=1.21
|
||||
progname=arg_parser
|
||||
srctrigger=doc/${pkgname}.texi
|
||||
|
||||
|
|
@ -26,6 +26,7 @@ CPPFLAGS=
|
|||
CFLAGS='-Wall -W -O2'
|
||||
CXXFLAGS='-Wall -W -O2'
|
||||
LDFLAGS=
|
||||
MAKEINFO=makeinfo
|
||||
|
||||
# checking whether we are using GNU C.
|
||||
/bin/sh -c "${CC} --version" > /dev/null 2>&1 || { CC=cc ; CFLAGS=-O2 ; }
|
||||
|
|
@ -62,7 +63,7 @@ while [ $# != 0 ] ; do
|
|||
echo "Options and variables: [defaults in brackets]"
|
||||
echo " -h, --help display this help and exit"
|
||||
echo " -V, --version output version information and exit"
|
||||
echo " --srcdir=DIR find the sources in DIR [. or ..]"
|
||||
echo " --srcdir=DIR find the source code in DIR [. or ..]"
|
||||
echo " --prefix=DIR install into DIR [${prefix}]"
|
||||
echo " --exec-prefix=DIR base directory for arch-dependent files [${exec_prefix}]"
|
||||
echo " --bindir=DIR user executables directory [${bindir}]"
|
||||
|
|
@ -71,12 +72,13 @@ while [ $# != 0 ] ; do
|
|||
echo " --mandir=DIR man pages directory [${mandir}]"
|
||||
echo " CC=COMPILER C compiler to use [${CC}]"
|
||||
echo " CXX=COMPILER C++ compiler to use [${CXX}]"
|
||||
echo " CPPFLAGS=OPTIONS command line options for the preprocessor [${CPPFLAGS}]"
|
||||
echo " CFLAGS=OPTIONS command line options for the C compiler [${CFLAGS}]"
|
||||
echo " CPPFLAGS=OPTIONS command-line options for the preprocessor [${CPPFLAGS}]"
|
||||
echo " CFLAGS=OPTIONS command-line options for the C compiler [${CFLAGS}]"
|
||||
echo " CFLAGS+=OPTIONS append options to the current value of CFLAGS"
|
||||
echo " CXXFLAGS=OPTIONS command line options for the C++ compiler [${CXXFLAGS}]"
|
||||
echo " CXXFLAGS=OPTIONS command-line options for the C++ compiler [${CXXFLAGS}]"
|
||||
echo " CXXFLAGS+=OPTIONS append options to the current value of CXXFLAGS"
|
||||
echo " LDFLAGS=OPTIONS command line options for the linker [${LDFLAGS}]"
|
||||
echo " LDFLAGS=OPTIONS command-line options for the linker [${LDFLAGS}]"
|
||||
echo " MAKEINFO=NAME makeinfo program to use [${MAKEINFO}]"
|
||||
echo
|
||||
exit 0 ;;
|
||||
--version | -V)
|
||||
|
|
@ -107,17 +109,16 @@ while [ $# != 0 ] ; do
|
|||
CXXFLAGS=*) CXXFLAGS=${optarg} ;;
|
||||
CXXFLAGS+=*) CXXFLAGS="${CXXFLAGS} ${optarg}" ;;
|
||||
LDFLAGS=*) LDFLAGS=${optarg} ;;
|
||||
MAKEINFO=*) MAKEINFO=${optarg} ;;
|
||||
|
||||
--*)
|
||||
echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;;
|
||||
--*) echo "configure: WARNING: unrecognized option: '${option}'" 1>&2 ;;
|
||||
*=* | *-*-*) ;;
|
||||
*)
|
||||
echo "configure: unrecognized option: '${option}'" 1>&2
|
||||
*) echo "configure: unrecognized option: '${option}'" 1>&2
|
||||
echo "Try 'configure --help' for more information." 1>&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
# Check if the option took a separate argument
|
||||
# Check whether the option took a separate argument
|
||||
if [ "${arg2}" = yes ] ; then
|
||||
if [ $# != 0 ] ; then args="${args} \"$1\"" ; shift
|
||||
else echo "configure: Missing argument to '${option}'" 1>&2
|
||||
|
|
@ -126,7 +127,7 @@ while [ $# != 0 ] ; do
|
|||
fi
|
||||
done
|
||||
|
||||
# Find the source files, if location was not specified.
|
||||
# Find the source code, if location was not specified.
|
||||
srcdirtext=
|
||||
if [ -z "${srcdir}" ] ; then
|
||||
srcdirtext="or . or .." ; srcdir=.
|
||||
|
|
@ -138,7 +139,7 @@ if [ -z "${srcdir}" ] ; then
|
|||
fi
|
||||
|
||||
if [ ! -r "${srcdir}/${srctrigger}" ] ; then
|
||||
echo "configure: Can't find sources in ${srcdir} ${srcdirtext}" 1>&2
|
||||
echo "configure: Can't find source code in ${srcdir} ${srcdirtext}" 1>&2
|
||||
echo "configure: (At least ${srctrigger} is missing)." 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -158,7 +159,7 @@ if [ -z "${no_create}" ] ; then
|
|||
# This script is free software: you have unlimited permission
|
||||
# to copy, distribute, and modify it.
|
||||
|
||||
exec /bin/sh $0 ${args} --no-create
|
||||
exec /bin/sh "$0" ${args} --no-create
|
||||
EOF
|
||||
chmod +x config.status
|
||||
fi
|
||||
|
|
@ -177,10 +178,11 @@ echo "CPPFLAGS = ${CPPFLAGS}"
|
|||
echo "CFLAGS = ${CFLAGS}"
|
||||
echo "CXXFLAGS = ${CXXFLAGS}"
|
||||
echo "LDFLAGS = ${LDFLAGS}"
|
||||
echo "MAKEINFO = ${MAKEINFO}"
|
||||
rm -f Makefile
|
||||
cat > Makefile << EOF
|
||||
# Makefile for Arg_parser - POSIX/GNU command line argument parser.
|
||||
# Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
# Makefile for Arg_parser - POSIX/GNU command-line argument parser.
|
||||
# Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
# This file was generated automatically by configure. Don't edit.
|
||||
#
|
||||
# This Makefile is free software: you have unlimited permission
|
||||
|
|
@ -202,6 +204,7 @@ CPPFLAGS = ${CPPFLAGS}
|
|||
CFLAGS = ${CFLAGS}
|
||||
CXXFLAGS = ${CXXFLAGS}
|
||||
LDFLAGS = ${LDFLAGS}
|
||||
MAKEINFO = ${MAKEINFO}
|
||||
EOF
|
||||
cat "${srcdir}/Makefile.in" >> Makefile
|
||||
|
||||
|
|
|
|||
31
thirdparty/arg_parser/doc/arg_parser.1
vendored
31
thirdparty/arg_parser/doc/arg_parser.1
vendored
|
|
@ -1,32 +1,34 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.16.
|
||||
.TH ARG_PARSER "1" "February 2022" "arg_parser 1.17" "User Commands"
|
||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.49.2.
|
||||
.TH ARG_PARSER "1" "March 2026" "arg_parser 1.21" "User Commands"
|
||||
.SH NAME
|
||||
arg_parser \- test program for Arg_parser
|
||||
.SH SYNOPSIS
|
||||
.B arg_parser
|
||||
[\fI\,options\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Arg_parser \- POSIX/GNU command line argument parser. (C++ version)
|
||||
Arg_parser \- POSIX/GNU command\-line argument parser. (C++ version)
|
||||
.PP
|
||||
Arg_parser is an argument parser that follows POSIX and GNU conventions for
|
||||
command line arguments. There exist C++ and C versions of Arg_parser. The
|
||||
command\-line arguments. There exist C++ and C versions of Arg_parser. The
|
||||
C++ version is implemented as a C++ class, while the C version is
|
||||
implemented as a single struct plus associated functions. Both are simpler,
|
||||
easier to use, and safer than 'getopt_long'.
|
||||
.PP
|
||||
For maximum stability, Arg_parser is self\-contained. It extracts all the
|
||||
information it needs from its arguments to avoid refering to them later.
|
||||
This avoids index\-out\-of\-bounds errors.
|
||||
information it needs from its arguments to avoid referring to them later.
|
||||
This avoids index\-out\-of\-bounds errors and allows the parser object to be
|
||||
passed as argument to other functions for further analysis.
|
||||
.PP
|
||||
Arg_parser does not modify its arguments, nor uses any global variables. So
|
||||
you may create more than one parser in your program if you need or want to.
|
||||
Arg_parser does not modify its arguments (argc, argv), nor uses any global
|
||||
variables.
|
||||
.PP
|
||||
The C++ version of Arg_parser can also parse options from configuration
|
||||
files.
|
||||
.PP
|
||||
To use Arg_parser in your own programs simply copy the files 'arg_parser.h'
|
||||
and 'arg_parser.cc' in your source tree. See the file 'main.cc' for an
|
||||
example of use.
|
||||
The C++ version of Arg_parser is provided in the files 'arg_parser.h' and
|
||||
\&'arg_parser.cc'. To learn how to use Arg_parser in your C++ programs, see
|
||||
the C++ example in the manual and the example file 'main.cc' in the source
|
||||
tarball.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
|
|
@ -44,10 +46,13 @@ example of option with required argument
|
|||
\fB\-c\fR, \fB\-\-casual[=\fR<arg>]
|
||||
example of option with optional argument
|
||||
.TP
|
||||
\fB\-e\fR, \fB\-\-empty=\fR<arg>
|
||||
example of option with maybe empty argument
|
||||
.TP
|
||||
\fB\-o\fR <arg>
|
||||
example of short only option
|
||||
.TP
|
||||
\fB\-\-orphan\fR
|
||||
\fB\-\-long\-only\fR
|
||||
example of long only option
|
||||
.TP
|
||||
\fB\-q\fR, \fB\-\-quiet\fR
|
||||
|
|
@ -63,7 +68,7 @@ Report bugs to arg\-parser\-bug@nongnu.org
|
|||
.br
|
||||
Arg_parser home page: http://www.nongnu.org/arg\-parser/arg_parser.html
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2022 Antonio Diaz Diaz.
|
||||
Copyright \(co 2026 Antonio Diaz Diaz.
|
||||
License 2\-clause BSD.
|
||||
.br
|
||||
This is free software: you are free to change and redistribute it.
|
||||
|
|
|
|||
572
thirdparty/arg_parser/doc/arg_parser.info
vendored
572
thirdparty/arg_parser/doc/arg_parser.info
vendored
|
|
@ -3,7 +3,7 @@ arg_parser.texi.
|
|||
|
||||
INFO-DIR-SECTION Libraries
|
||||
START-INFO-DIR-ENTRY
|
||||
* Arg_parser: (arg_parser). A POSIX/GNU command line argument parser
|
||||
* Arg_parser: (arg_parser). A POSIX/GNU command-line argument parser
|
||||
END-INFO-DIR-ENTRY
|
||||
|
||||
|
||||
|
|
@ -12,22 +12,24 @@ File: arg_parser.info, Node: Top, Next: Introduction, Up: (dir)
|
|||
Arg_parser Manual
|
||||
*****************
|
||||
|
||||
This manual is for Arg_parser (version 1.17, 5 February 2022).
|
||||
This manual is for Arg_parser (version 1.21, 10 March 2026).
|
||||
|
||||
* Menu:
|
||||
|
||||
* Introduction:: Purpose and features of Arg_parser
|
||||
* Argument syntax:: By convention, options start with a hyphen
|
||||
* Initialization:: Parsing arguments and reporting errors
|
||||
* Using Arg_parser:: Reading the options and arguments parsed
|
||||
* C++ version:: Using the C++ version of Arg_parser
|
||||
* C version:: Using the C version of Arg_parser
|
||||
* C++ example:: Tutorial for the C++ version
|
||||
* C example:: Tutorial for the C version
|
||||
* Problems:: Reporting bugs
|
||||
* Concept index:: Index of concepts
|
||||
* Function index:: Index of functions, constants, and variables
|
||||
|
||||
|
||||
Copyright (C) 2006-2022 Antonio Diaz Diaz.
|
||||
Copyright (C) 2006-2026 Antonio Diaz Diaz.
|
||||
|
||||
This manual is free documentation: you have unlimited permission to copy,
|
||||
This manual is free documentation: you have unlimited permission to copy,
|
||||
distribute, and modify it.
|
||||
|
||||
|
||||
|
|
@ -37,94 +39,135 @@ File: arg_parser.info, Node: Introduction, Next: Argument syntax, Prev: Top,
|
|||
**************
|
||||
|
||||
Arg_parser is an argument parser that follows POSIX and GNU conventions for
|
||||
command line arguments. There exist C++ and C versions of Arg_parser. The
|
||||
command-line arguments. There exist C++ and C versions of Arg_parser. The
|
||||
C++ version is implemented as a C++ class, while the C version is
|
||||
implemented as a single struct plus associated functions. Both are simpler,
|
||||
easier to use, and safer than 'getopt_long'.
|
||||
|
||||
For maximum stability, Arg_parser is self-contained. It extracts all the
|
||||
information it needs from its arguments to avoid refering to them later.
|
||||
This avoids index-out-of-bounds errors.
|
||||
For maximum stability, Arg_parser is self-contained. It extracts all the
|
||||
information it needs from its arguments to avoid referring to them later.
|
||||
This avoids index-out-of-bounds errors and allows the parser object to be
|
||||
passed as argument to other functions for further analysis.
|
||||
|
||||
Arg_parser does not modify its arguments, nor uses any global variables.
|
||||
So you may create more than one parser in your program if you need or want
|
||||
to.
|
||||
Arg_parser does not modify its arguments (argc, argv), nor uses any global
|
||||
variables.
|
||||
|
||||
The C++ version of Arg_parser can also parse options from configuration
|
||||
The C++ version of Arg_parser can also parse options from configuration
|
||||
files.
|
||||
|
||||
Arg_parser was developed as the argument parser for GNU moe, because
|
||||
moe's argument parsing is rather complex. Then I used it in my other
|
||||
projects, including GNU ddrescue, GNU ed, lzip, GNU ocrad, tarlz, and
|
||||
zutils, with excellent results.
|
||||
Arg_parser was developed as the argument parser for GNU moe, because moe's
|
||||
argument parsing is rather complex. Then I used it in my other projects,
|
||||
including GNU ddrescue, GNU ed, lzip, GNU ocrad, tarlz, and zutils, with
|
||||
excellent results.
|
||||
|
||||
1.1 Differences with 'getopt' and 'getopt_long'.
|
||||
================================================
|
||||
|
||||
'getopt' parses the options one by one, which requires internal state. Part
|
||||
of this state is stored in several global variables, and part of it is
|
||||
hidden. For example, the POSIX specification of 'getopt' states that:
|
||||
|
||||
When an element of argv[] contains multiple option characters, it is
|
||||
unspecified how getopt() determines which options have already been
|
||||
processed.
|
||||
|
||||
Parsing the options one by one is also a lot of work for the application,
|
||||
which must check for errors (invalid option, missing option argument, etc)
|
||||
for each option. 'getopt' is the 1970s way of parsing command-line
|
||||
arguments.
|
||||
|
||||
'getopt_long' is a not-very-well-designed extension on top of 'getopt'. In
|
||||
addition to parsing the options one by one as 'getopt' does, 'getopt_long'
|
||||
accepts configuration data from two overlapping sources, which makes it
|
||||
easy for errors in the configuration to remain undetected. For example, a
|
||||
certain long option can be declared to be equivalent to a given short
|
||||
option, but both forms of the option may contain contradictory requirements
|
||||
for the option's argument.
|
||||
|
||||
OTOH, Arg_parser parses the whole command line at once and fills a struct
|
||||
with the results, like 'gmtime_r' and 'stat' do. This way, errors are
|
||||
checked once, there is no need to permute the elements of argv, and the
|
||||
struct returned can be used undisturbed by later changes in argv.
|
||||
|
||||
Finally, using Arg_parser instead of 'getopt_long' reduces the size of your
|
||||
source code because, as 'getopt_long' is not available on all systems, a
|
||||
portable program using it needs to ship its (larger) source anyway.
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Argument syntax, Next: Initialization, Prev: Introduction, Up: Top
|
||||
File: arg_parser.info, Node: Argument syntax, Next: C++ version, Prev: Introduction, Up: Top
|
||||
|
||||
2 Syntax of command line arguments
|
||||
2 Syntax of command-line arguments
|
||||
**********************************
|
||||
|
||||
POSIX recommends these conventions for command line arguments. Arg_parser
|
||||
POSIX recommends these conventions for command-line arguments. Arg_parser
|
||||
makes it easy to implement them.
|
||||
|
||||
* A command line argument is an option if it begins with a hyphen
|
||||
delimiter ('-').
|
||||
|
||||
* Multiple options may follow a hyphen delimiter in a single token if
|
||||
the options don't take arguments. Thus, '-abc' is equivalent to
|
||||
'-a -b -c'.
|
||||
* A command-line argument is an option if it begins with a hyphen ('-').
|
||||
|
||||
* Option names are single alphanumeric characters.
|
||||
|
||||
* Certain options require an argument.
|
||||
|
||||
* An option and its argument may or may not appear as separate tokens.
|
||||
(In other words, the whitespace separating them is optional). Thus,
|
||||
'-o foo' and '-ofoo' are equivalent.
|
||||
(In other words, the whitespace separating them is optional, unless the
|
||||
argument is the empty string). Thus, '-o foo' and '-ofoo' are
|
||||
equivalent.
|
||||
|
||||
* One or more options without arguments, followed by at most one option
|
||||
that takes an argument, may follow a hyphen in a single token. Thus,
|
||||
'-abc' is equivalent to '-a -b -c'.
|
||||
|
||||
* Options typically precede other non-option arguments.
|
||||
|
||||
Arg_parser normally makes it appear as if all the option arguments were
|
||||
Arg_parser normally makes it appear as if all the options were
|
||||
specified before all the non-option arguments for the purposes of
|
||||
parsing, even if the user of your program intermixed option and
|
||||
parsing, even if the user of your program intermixed options and
|
||||
non-option arguments. If you want the arguments in the exact order the
|
||||
user typed them, call 'Arg_parser' with IN_ORDER = true.
|
||||
user typed them, call 'Arg_parser' with FLAGS = 'in_order'.
|
||||
|
||||
* The argument '--' terminates all options; any following arguments are
|
||||
treated as non-option arguments, even if they begin with a hyphen.
|
||||
|
||||
* A token consisting of a single hyphen character is interpreted as an
|
||||
ordinary non-option argument. By convention, it is used to specify
|
||||
input from or output to the standard input and output streams.
|
||||
standard input, standard output, or a file named '-'.
|
||||
|
||||
* Options may be supplied in any order, or appear multiple times. The
|
||||
interpretation is left up to the particular application program.
|
||||
|
||||
* GNU adds "long options" to these conventions. Long options consist of
|
||||
'--' followed by a name made of alphanumeric characters and hyphens.
|
||||
Option names are typically one to three words long, with hyphens to
|
||||
separate words. Users can abbreviate the option names as long as the
|
||||
abbreviations are unique.
|
||||
GNU adds "long options" to these conventions:
|
||||
|
||||
* A long option consists of two hyphens ('--') followed by a name made
|
||||
of alphanumeric characters and hyphens. Option names are typically one
|
||||
to three words long, with hyphens to separate words. Abbreviations can
|
||||
be used for the long option names as long as the abbreviations are
|
||||
unique.
|
||||
|
||||
* A long option and its argument may or may not appear as separate
|
||||
tokens. In the latter case they must be separated by an equal sign '='.
|
||||
Thus, '--foo bar' and '--foo=bar' are equivalent.
|
||||
|
||||
* The syntax for optional option arguments is
|
||||
'-<short_option><argument>' (without whitespace), or
|
||||
'--<long_option>=<argument>'.
|
||||
The syntax of options with an optional argument is
|
||||
'-<short_option><argument>' (without whitespace), or
|
||||
'--<long_option>=<argument>'.
|
||||
|
||||
The syntax of options with an empty argument is '-<short_option> ""',
|
||||
'--<long_option> ""', or '--<long_option>=""'.
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Initialization, Next: Using Arg_parser, Prev: Argument syntax, Up: Top
|
||||
File: arg_parser.info, Node: C++ version, Next: C version, Prev: Argument syntax, Up: Top
|
||||
|
||||
3 Parsing arguments and reporting errors
|
||||
****************************************
|
||||
3 Using the C++ version of Arg_parser
|
||||
*************************************
|
||||
|
||||
To use Arg_parser in your own programs first copy the files 'arg_parser.h'
|
||||
and 'arg_parser.cc' in your source tree. See the file 'main.cc' for an
|
||||
example of use.
|
||||
The C++ version of Arg_parser is provided in the files 'arg_parser.h' and
|
||||
'arg_parser.cc'. To learn how to use Arg_parser in your C++ programs, *note
|
||||
C++ example::, and the file 'main.cc' in the source tarball.
|
||||
|
||||
The class 'Arg_parser' has two constructors; one to parse command line
|
||||
3.1 Parsing arguments and reporting errors
|
||||
==========================================
|
||||
|
||||
The class 'Arg_parser' has two constructors; one to parse command-line
|
||||
arguments from ARGV, and the other to parse a single token from a
|
||||
configuration file or other source.
|
||||
|
||||
|
|
@ -132,28 +175,69 @@ configuration file or other source.
|
|||
This structure describes a single option for the sake of 'Arg_parser'.
|
||||
The argument OPTIONS must be an array of these structures, one for
|
||||
each option. Terminate the array with an element containing a code
|
||||
which is zero.
|
||||
which is zero. 'struct Option' has the following members:
|
||||
|
||||
'struct Option' has the following members:
|
||||
|
||||
'int code'
|
||||
-- Member: 'int' code
|
||||
This member is the code that identifies the option, normally the
|
||||
short-option character. Must be different from 0. A code value
|
||||
outside the unsigned char range means a long-only option.
|
||||
|
||||
'const char * long_name'
|
||||
-- Member: 'const char *' long_name
|
||||
This member is the long option name. It is a zero-terminated
|
||||
string. A null or empty long_name means a short-only option.
|
||||
|
||||
'enum Has_arg has_arg'
|
||||
-- Member: 'enum Has_arg' has_arg
|
||||
This member says whether the option takes an argument. It has
|
||||
three valid values: 'no', 'yes', and 'maybe'.
|
||||
four valid values: 'no', 'yes', 'maybe', and 'yesme', meaning
|
||||
respectively 'no argument', 'non-empty argument required',
|
||||
'optional argument', and 'argument required, but it may be the
|
||||
empty string'. 'yesme' is not recommended.
|
||||
|
||||
If an empty argument is passed to an option specified as 'yesme',
|
||||
it must be in a separate command-line argument or specified as a
|
||||
long option with the empty string after the '=' character. It
|
||||
can't be specified as the empty string after the short option.
|
||||
|
||||
-- Data Type: enum Flags
|
||||
The argument FLAGS is a bit mask. You can bitwise-OR the following
|
||||
constants and assign them to FLAGS to modify the way in which the
|
||||
arguments are parsed. FLAGS = 0 chooses the default behavior (reorder
|
||||
the options to put them before the non-option arguments).
|
||||
|
||||
-- Constant: 'Flags' in_order
|
||||
Store the arguments in the exact order the user typed them,
|
||||
without reordering the options to put them before the non-option
|
||||
arguments.
|
||||
|
||||
-- Constant: 'Flags' in_order_stop
|
||||
Stop option processing when finding the first non-option argument
|
||||
as if the argument '--' had been found before it. Store the first
|
||||
non-option argument and all the arguments following it as
|
||||
non-option arguments, even if they begin with a hyphen. This is
|
||||
similar to the POSIX function 'getopt', which stops option
|
||||
processing after finding the first non-option argument.
|
||||
|
||||
-- Constant: 'Flags' in_order_skip
|
||||
Parse only the heading options. Skip the first non-option
|
||||
argument and all the arguments following it; do not parse nor
|
||||
store them. The function 'argv_index' returns the index in ARGV
|
||||
of the first argument skipped (the first non-option argument), or
|
||||
ARGC if no arguments were skipped. This mode is useful for
|
||||
parsing the command line of programs that invoke other programs,
|
||||
like 'timeout', 'xargs', or 'valgrind'.
|
||||
|
||||
-- Constant: 'Flags' neg_non_opt
|
||||
Parse the negative numbers, including '-inf', '-Inf', and '-INF',
|
||||
as non-option arguments without reordering them. Numbers start
|
||||
with a digit or a period and a digit. This mode is useful for
|
||||
parsing the command line of tools like 'seq' which take negative
|
||||
numbers as arguments.
|
||||
|
||||
-- Function: Arg_parser ( const int ARGC, const char * const ARGV[], const
|
||||
Option OPTIONS[], const bool IN_ORDER = false )
|
||||
Option OPTIONS[], const int FLAGS = 0 )
|
||||
Constructor. Reads the arguments in ARGV and parses all options,
|
||||
option arguments, and non-option arguments contained in them. In case
|
||||
of error, 'error().size()' will be non-zero.
|
||||
of error, 'error().size()' returns nonzero.
|
||||
|
||||
-- Function: Arg_parser ( const char * const OPT, const char * const ARG,
|
||||
const Option OPTIONS[] )
|
||||
|
|
@ -161,22 +245,25 @@ configuration file or other source.
|
|||
token in case an argument is needed for an option parsed). Can be used
|
||||
to parse options from a configuration file one at a time. Be warned
|
||||
that a single token may produce an undefined number of short options.
|
||||
In case of error, 'error().size()' will be non-zero.
|
||||
In case of error, 'error().size()' returns nonzero.
|
||||
|
||||
-- Function: const std::string & error () const
|
||||
Use this funtion to verify that the arguments have been correctly
|
||||
parsed by the constructor. If there was an error parsing the arguments,
|
||||
'error' returns a non-empty error message explaining the cause.
|
||||
Use this funtion to check that the arguments have been correctly
|
||||
parsed by the constructor. If there was an error parsing the
|
||||
arguments, 'error' returns an error message explaining the cause, else
|
||||
it returns an empty string.
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Using Arg_parser, Next: C version, Prev: Initialization, Up: Top
|
||||
-- Function: int argv_index () const
|
||||
Return the index in ARGV of the first argument skipped (the first
|
||||
non-option argument) when FLAGS was set to 'in_order_skip'. If no
|
||||
arguments were skipped, ARGC is returned instead.
|
||||
|
||||
4 Using the class 'Arg_parser'
|
||||
******************************
|
||||
3.2 Reading the options and arguments parsed
|
||||
============================================
|
||||
|
||||
After a successful call to the constructor, which must be verified by
|
||||
calling 'error', the options and arguments parsed can be accessed by means
|
||||
of the following functions:
|
||||
After a successful call to the constructor, which must be checked by calling
|
||||
'error', the options and arguments parsed can be accessed by means of the
|
||||
following functions:
|
||||
|
||||
-- Function: int arguments () const
|
||||
This function returns the number of options and non-option arguments
|
||||
|
|
@ -185,8 +272,8 @@ of the following functions:
|
|||
-- Function: int code ( const int I ) const
|
||||
This function returns the code of the option at position I. Valid
|
||||
values for I range from 0 to 'arguments() - 1'. If the code returned
|
||||
is non-zero, 'argument(I)' is the option's argument (or is empty if
|
||||
the option does not have an argument). If the code returned is zero,
|
||||
is nonzero, 'argument(I)' is the option's argument (or is empty if the
|
||||
option does not have an argument). If the code returned is zero,
|
||||
'argument(I)' is a non-option argument.
|
||||
|
||||
-- Function: const std::string & parsed_name ( const int I ) const
|
||||
|
|
@ -199,80 +286,291 @@ of the following functions:
|
|||
This function returns the argument at position I. It may be the
|
||||
argument of an option or a non-option argument, depending on the value
|
||||
returned by 'code(I)'. Valid values for I range from 0 to
|
||||
'arguments() - 1'.
|
||||
'arguments() - 1'. If the argument does not exist, the empty string is
|
||||
returned.
|
||||
|
||||
|
||||
File: arg_parser.info, Node: C version, Next: Problems, Prev: Using Arg_parser, Up: Top
|
||||
File: arg_parser.info, Node: C version, Next: C++ example, Prev: C++ version, Up: Top
|
||||
|
||||
5 Using the C version of Arg_parser
|
||||
4 Using the C version of Arg_parser
|
||||
***********************************
|
||||
|
||||
To use the C version of Arg_parser in your own programs first copy the files
|
||||
'carg_parser.h' and 'carg_parser.c' in your source tree. See the file
|
||||
'cmain.c' for an example of use.
|
||||
The C version of Arg_parser is provided in the files 'carg_parser.h' and
|
||||
'carg_parser.c'. To learn how to use Arg_parser in your C programs, *note C
|
||||
example::, and the file 'cmain.c' in the source tarball.
|
||||
|
||||
Then you need to declare a variable of type 'struct Arg_parser', pass
|
||||
its address to 'ap_init' to initialize it, and verify that 'ap_error'
|
||||
returns 0.
|
||||
4.1 Parsing arguments and reporting errors
|
||||
==========================================
|
||||
|
||||
'struct ap_Option' is identical to 'struct Option', except that
|
||||
'Has_arg' becomes 'ap_Has_arg', and the names of its three values are also
|
||||
prefixed with 'ap_'. *Note struct Option::, for details about the members.
|
||||
You need to declare a variable of type 'Arg_parser', pass its address to
|
||||
'ap_init' to initialize it, and check that 'ap_error' returns 0.
|
||||
|
||||
-- Function: char ap_init ( struct Arg_parser * const AP, const int ARGC,
|
||||
const char * const ARGV[], const struct ap_Option OPTIONS[],
|
||||
const char IN_ORDER )
|
||||
'struct ap_Option' is identical to 'struct Option', except that 'Has_arg'
|
||||
becomes 'ap_Has_arg', and the names of its four values are also prefixed
|
||||
with 'ap_'. *Note struct Option::, for details about the members.
|
||||
|
||||
'enum ap_Flags' is identical to 'enum Flags', except that its constants are
|
||||
also prefixed with 'ap_'. *Note enum Flags::, for a description of the
|
||||
constants.
|
||||
|
||||
-- Function: char ap_init ( Arg_parser * const AP, const int ARGC, const
|
||||
char * const ARGV[], const ap_Option OPTIONS[], const int FLAGS )
|
||||
Reads the arguments in ARGV and parses all options, option arguments,
|
||||
and non-option arguments contained in them. Returns 0 if there is not
|
||||
enough memory, else 1. In case of error, 'ap_error' will return a
|
||||
non-null pointer.
|
||||
enough memory, else 1 (even if errors are found). In case of error,
|
||||
'ap_error' returns a non-null pointer.
|
||||
|
||||
-- Function: void ap_free ( struct Arg_parser * const AP )
|
||||
-- Function: void ap_free ( Arg_parser * const AP )
|
||||
Frees all dynamically allocated data structures.
|
||||
|
||||
-- Function: const char * ap_error ( const struct Arg_parser * const AP )
|
||||
Use this funtion to verify that the arguments have been correctly
|
||||
-- Function: const char * ap_error ( const Arg_parser * const AP )
|
||||
Use this funtion to check that the arguments have been correctly
|
||||
parsed by 'ap_init'. If there was an error parsing the arguments,
|
||||
'ap_error' returns a pointer to an error message explaining the cause,
|
||||
else it returns a null pointer.
|
||||
|
||||
After a successful call to 'ap_init', which must be verified by calling
|
||||
-- Function: int ap_argv_index ( const Arg_parser * const AP )
|
||||
Return the index in ARGV of the first argument skipped (the first
|
||||
non-option argument) when FLAGS was set to 'ap_in_order_skip'. If no
|
||||
arguments were skipped, ARGC is returned instead.
|
||||
|
||||
4.2 Reading the options and arguments parsed
|
||||
============================================
|
||||
|
||||
After a successful call to 'ap_init', which must be checked by calling
|
||||
'ap_error', the options and arguments parsed can be accessed by means of
|
||||
the following functions:
|
||||
|
||||
-- Function: int ap_arguments ( const struct Arg_parser * const AP )
|
||||
-- Function: int ap_arguments ( const Arg_parser * const AP )
|
||||
This function returns the number of options and non-option arguments
|
||||
parsed. This number is usually different from argc.
|
||||
|
||||
-- Function: int ap_code ( const struct Arg_parser * const AP, const int I
|
||||
)
|
||||
-- Function: int ap_code ( const Arg_parser * const AP, const int I )
|
||||
This function returns the code of the option at position I. Valid
|
||||
values for I range from 0 to 'ap_arguments() - 1'. If the code
|
||||
returned is non-zero, 'ap_argument(I)' is the option's argument (or is
|
||||
returned is nonzero, 'ap_argument(I)' is the option's argument (or is
|
||||
empty if the option does not have an argument). If the code returned
|
||||
is zero, 'ap_argument(I)' is a non-option argument.
|
||||
|
||||
-- Function: const char * ap_parsed_name ( const struct Arg_parser * const
|
||||
AP, const int I )
|
||||
-- Function: const char * ap_parsed_name ( const Arg_parser * const AP,
|
||||
const int I )
|
||||
This function returns the full name of the option parsed (short or
|
||||
long) at position I. It may be useful to produce more accurate
|
||||
diagnostic messages. For non-option arguments it returns the empty
|
||||
string.
|
||||
|
||||
-- Function: const char * ap_argument ( const struct Arg_parser * const
|
||||
AP, const int I )
|
||||
-- Function: const char * ap_argument ( const Arg_parser * const AP, const
|
||||
int I )
|
||||
This function returns the argument at position I. It may be the
|
||||
argument of an option or a non-option argument, depending on the value
|
||||
returned by 'ap_code(I)'. Valid values for I range from 0 to
|
||||
'ap_arguments() - 1'.
|
||||
'ap_arguments() - 1'. If the argument does not exist, the empty string
|
||||
is returned.
|
||||
|
||||
When you are finished, you should free all dynamically allocated data
|
||||
When you are finished, you should free all dynamically allocated data
|
||||
structures by calling 'ap_free'.
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Problems, Next: Concept index, Prev: C version, Up: Top
|
||||
File: arg_parser.info, Node: C++ example, Next: C example, Prev: C version, Up: Top
|
||||
|
||||
6 Reporting bugs
|
||||
5 Tutorial for the C++ version
|
||||
******************************
|
||||
|
||||
This tutorial uses lzip as an example of how to use Arg_parser in a C++
|
||||
program. You need to follow these 6 steps:
|
||||
|
||||
First copy the files 'arg_parser.h' and 'arg_parser.cc' in your source
|
||||
tree, in the same directory as the file containing the function 'main' of
|
||||
your program. In lzip, 'main' is in 'main.cc'.
|
||||
|
||||
Second, include these header files near the top of 'main.cc':
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "arg_parser.h"
|
||||
|
||||
Third, define inside 'main' the option names and argument requirements.
|
||||
Lzip defines the following options:
|
||||
|
||||
const Arg_parser::Option options[] = {
|
||||
{ '0', "fast", Arg_parser::no },
|
||||
{ '1', 0, Arg_parser::no },
|
||||
{ '2', 0, Arg_parser::no },
|
||||
{ '3', 0, Arg_parser::no },
|
||||
{ '4', 0, Arg_parser::no },
|
||||
{ '5', 0, Arg_parser::no },
|
||||
{ '6', 0, Arg_parser::no },
|
||||
{ '7', 0, Arg_parser::no },
|
||||
{ '8', 0, Arg_parser::no },
|
||||
{ '9', "best", Arg_parser::no },
|
||||
{ 'a', "trailing-error", Arg_parser::no },
|
||||
{ 'b', "member-size", Arg_parser::yes },
|
||||
{ 'c', "stdout", Arg_parser::no },
|
||||
{ 'd', "decompress", Arg_parser::no },
|
||||
{ 'f', "force", Arg_parser::no },
|
||||
{ 'F', "recompress", Arg_parser::no },
|
||||
{ 'h', "help", Arg_parser::no },
|
||||
{ 'k', "keep", Arg_parser::no },
|
||||
{ 'l', "list", Arg_parser::no },
|
||||
{ 'm', "match-length", Arg_parser::yes },
|
||||
{ 'n', "threads", Arg_parser::yes },
|
||||
{ 'o', "output", Arg_parser::yes },
|
||||
{ 'q', "quiet", Arg_parser::no },
|
||||
{ 's', "dictionary-size", Arg_parser::yes },
|
||||
{ 'S', "volume-size", Arg_parser::yes },
|
||||
{ 't', "test", Arg_parser::no },
|
||||
{ 'v', "verbose", Arg_parser::no },
|
||||
{ 'V', "version", Arg_parser::no },
|
||||
{ opt_lt, "loose-trailing", Arg_parser::no },
|
||||
{ 0, 0, Arg_parser::no } };
|
||||
|
||||
Fourth, declare and initialize the parser:
|
||||
|
||||
const Arg_parser parser( argc, argv, options );
|
||||
if( parser.error().size() ) // bad option
|
||||
{ show_error( parser.error().c_str(), 0, true ); return 1; }
|
||||
|
||||
Fifth, perform the actions corresponding to each option parsed. Lzip
|
||||
performs the following actions:
|
||||
|
||||
int argind = 0;
|
||||
for( ; argind < parser.arguments(); ++argind )
|
||||
{
|
||||
const int code = parser.code( argind );
|
||||
if( !code ) break; // no more options
|
||||
const char * const pn = parser.parsed_name( argind ).c_str();
|
||||
const std::string & sarg = parser.argument( argind );
|
||||
const char * const arg = sarg.c_str();
|
||||
switch( code )
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9': zero = code == '0';
|
||||
encoder_options = option_mapping[code-'0']; break;
|
||||
case 'a': cl_opts.ignore_trailing = false; break;
|
||||
case 'b': member_size = getnum(arg, pn, 100000, max_member_size); break;
|
||||
case 'c': to_stdout = true; break;
|
||||
case 'd': set_mode( program_mode, m_decompress ); break;
|
||||
case 'f': force = true; break;
|
||||
case 'F': recompress = true; break;
|
||||
case 'h': show_help(); return 0;
|
||||
case 'k': keep_input_files = true; break;
|
||||
case 'l': set_mode( program_mode, m_list ); break;
|
||||
case 'm': encoder_options.match_len_limit =
|
||||
getnum( arg, pn, min_match_len_limit, max_match_len );
|
||||
zero = false; break;
|
||||
case 'n': break; // ignored
|
||||
case 'o': if( sarg == "-" ) to_stdout = true;
|
||||
else { default_output_filename = sarg; } break;
|
||||
case 'q': verbosity = -1; break;
|
||||
case 's': encoder_options.dictionary_size = get_dict_size( arg, pn );
|
||||
zero = false; break;
|
||||
case 'S': volume_size = getnum(arg, pn, 100000, max_volume_size); break;
|
||||
case 't': set_mode( program_mode, m_test ); break;
|
||||
case 'v': if( verbosity < 4 ) ++verbosity; break;
|
||||
case 'V': show_version(); return 0;
|
||||
case opt_lt: cl_opts.loose_trailing = true; break;
|
||||
default: internal_error( "uncaught option." );
|
||||
}
|
||||
} // end process options
|
||||
|
||||
Sixth, process any remaining non-option arguments (file names in the case of
|
||||
lzip):
|
||||
|
||||
std::vector< std::string > filenames;
|
||||
bool filenames_given = false;
|
||||
for( ; argind < parser.arguments(); ++argind )
|
||||
{
|
||||
filenames.push_back( parser.argument( argind ) );
|
||||
if( filenames.back() != "-" ) filenames_given = true;
|
||||
}
|
||||
if( filenames.empty() ) filenames.push_back("-");
|
||||
// do something with 'filenames'
|
||||
|
||||
|
||||
File: arg_parser.info, Node: C example, Next: Problems, Prev: C++ example, Up: Top
|
||||
|
||||
6 Tutorial for the C version
|
||||
****************************
|
||||
|
||||
This tutorial uses GNU ed as an example of how to use Arg_parser in a C
|
||||
program. You need to follow these 6 steps:
|
||||
|
||||
First copy the files 'carg_parser.h' and 'carg_parser.c' in your source
|
||||
tree, in the same directory as the file containing the function 'main' of
|
||||
your program. In GNU ed, 'main' is in 'main.c'.
|
||||
|
||||
Second, include the header 'carg_parser.h' near the top of 'main.c':
|
||||
|
||||
#include "carg_parser.h"
|
||||
|
||||
Third, define inside 'main' the option names and argument requirements. Ed
|
||||
defines the following options:
|
||||
|
||||
const ap_Option options[] = {
|
||||
{ 'E', "extended-regexp", ap_no },
|
||||
{ 'G', "traditional", ap_no },
|
||||
{ 'h', "help", ap_no },
|
||||
{ 'l', "loose-exit-status", ap_no },
|
||||
{ 'p', "prompt", ap_yes },
|
||||
{ 'q', "quiet", ap_no },
|
||||
{ 'q', "silent", ap_no },
|
||||
{ 'r', "restricted", ap_no },
|
||||
{ 's', "script", ap_no },
|
||||
{ 'v', "verbose", ap_no },
|
||||
{ 'V', "version", ap_no },
|
||||
{ opt_cr, "strip-trailing-cr", ap_no },
|
||||
{ opt_un, "unsafe-names", ap_no },
|
||||
{ 0, 0, ap_no } };
|
||||
|
||||
Fourth, declare and initialize the parser:
|
||||
|
||||
Arg_parser parser;
|
||||
if( !ap_init( &parser, argc, argv, options, 0 ) )
|
||||
{ show_error( "Memory exhausted.", 0, false ); return 1; }
|
||||
if( ap_error( &parser ) ) /* bad option */
|
||||
{ show_error( ap_error( &parser ), 0, true ); return 1; }
|
||||
|
||||
Fifth, perform the actions corresponding to each option parsed. Ed performs
|
||||
the following actions:
|
||||
|
||||
int argind = 0;
|
||||
for( ; argind < ap_arguments( &parser ); ++argind )
|
||||
{
|
||||
const int code = ap_code( &parser, argind );
|
||||
if( !code ) break; /* no more options */
|
||||
const char * const arg = ap_argument( &parser, argind );
|
||||
switch( code )
|
||||
{
|
||||
case 'E': extended_regexp_ = true; break;
|
||||
case 'G': traditional_ = true; break; /* backward compatibility */
|
||||
case 'h': show_help(); return 0;
|
||||
case 'l': loose = true; break;
|
||||
case 'p': if( set_prompt( arg ) ) break; else return 1;
|
||||
case 'q': quiet = true; break;
|
||||
case 'r': restricted_ = true; break;
|
||||
case 's': scripted_ = true; break;
|
||||
case 'v': set_verbose(); break;
|
||||
case 'V': show_version(); return 0;
|
||||
case opt_cr: strip_cr_ = true; break;
|
||||
case opt_un: safe_names = false; break;
|
||||
default: show_error( "internal error: uncaught option.", 0, false );
|
||||
return 3;
|
||||
}
|
||||
} /* end process options */
|
||||
|
||||
Sixth, process any remaining non-option arguments (line number and file
|
||||
name in the case of ed):
|
||||
|
||||
for( ; argind < ap_arguments( &parser ); ++argind )
|
||||
{
|
||||
const char * const arg = ap_argument( &parser, argind );
|
||||
/* do something with 'arg' */
|
||||
}
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Problems, Next: Concept index, Prev: C example, Up: Top
|
||||
|
||||
7 Reporting bugs
|
||||
****************
|
||||
|
||||
There are probably bugs in Arg_parser. There are certainly errors and
|
||||
|
|
@ -280,12 +578,12 @@ omissions in this manual. If you report them, they will get fixed. If you
|
|||
don't, no one will ever know about them and they will remain unfixed for
|
||||
all eternity, if not longer.
|
||||
|
||||
If you find a bug in Arg_parser, please send electronic mail to
|
||||
If you find a bug in Arg_parser, please send electronic mail to
|
||||
<arg-parser-bug@nongnu.org>. Include the version number, which you can find
|
||||
by running 'arg_parser --version'.
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Concept index, Prev: Problems, Up: Top
|
||||
File: arg_parser.info, Node: Concept index, Next: Function index, Prev: Problems, Up: Top
|
||||
|
||||
Concept index
|
||||
*************
|
||||
|
|
@ -295,24 +593,68 @@ Concept index
|
|||
|
||||
* argument syntax: Argument syntax. (line 6)
|
||||
* bugs: Problems. (line 6)
|
||||
* C example: C example. (line 6)
|
||||
* C version: C version. (line 6)
|
||||
* C++ example: C++ example. (line 6)
|
||||
* C++ version: C++ version. (line 6)
|
||||
* getting help: Problems. (line 6)
|
||||
* initialization: Initialization. (line 6)
|
||||
* introduction: Introduction. (line 6)
|
||||
* using Arg_parser: Using Arg_parser. (line 6)
|
||||
|
||||
|
||||
File: arg_parser.info, Node: Function index, Prev: Concept index, Up: Top
|
||||
|
||||
Index of constants and variables
|
||||
********************************
|
||||
|
||||
| ||||