mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-12 01:26:48 +08:00
use autogen for command line options
This commit is contained in:
@@ -17,3 +17,6 @@ gl/libgnu.a
|
||||
gl/arg-nonnull.h
|
||||
gl/warn-on-use.h
|
||||
gl/c++defs.h
|
||||
src/ocserv.1
|
||||
libopts/libopts.a
|
||||
build-aux/compile
|
||||
|
||||
+3
-2
@@ -1,3 +1,4 @@
|
||||
SUBDIRS = gl src
|
||||
SUBDIRS = gl libopts src
|
||||
|
||||
ACLOCAL_AMFLAGS = -I gl/m4 -I libopts/m4
|
||||
|
||||
ACLOCAL_AMFLAGS = -I gl/m4
|
||||
|
||||
Vendored
+36
@@ -812,6 +812,41 @@ AC_MSG_RESULT([$_am_result])
|
||||
rm -f confinc confmf
|
||||
])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6
|
||||
|
||||
# AM_PROG_CC_C_O
|
||||
# --------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake.
|
||||
AC_DEFUN([AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([compile])dnl
|
||||
# FIXME: we rely on the cache variable name because
|
||||
# there is no other way.
|
||||
set dummy $CC
|
||||
am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
|
||||
eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
|
||||
if test "$am_t" != yes; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
dnl Make sure AC_PROG_CC is never called again, or it will override our
|
||||
dnl setting of CC.
|
||||
m4_define([AC_PROG_CC],
|
||||
[m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
|
||||
])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||
@@ -1186,6 +1221,7 @@ AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([libopts/m4/libopts.m4])
|
||||
m4_include([gl/m4/00gnulib.m4])
|
||||
m4_include([gl/m4/extensions.m4])
|
||||
m4_include([gl/m4/gnulib-common.m4])
|
||||
|
||||
+229
-1
@@ -15,6 +15,12 @@
|
||||
/* Define to the number of bits in type 'wint_t'. */
|
||||
#undef BITSIZEOF_WINT_T
|
||||
|
||||
/* fopen(3) accepts a 'b' in the mode flag */
|
||||
#undef FOPEN_BINARY_FLAG
|
||||
|
||||
/* fopen(3) accepts a 't' in the mode flag */
|
||||
#undef FOPEN_TEXT_FLAG
|
||||
|
||||
/* Define to 1 when the gnulib module memchr should be tested. */
|
||||
#undef GNULIB_TEST_MEMCHR
|
||||
|
||||
@@ -24,16 +30,71 @@
|
||||
/* Define to 1 if you have the <bp-sym.h> header file. */
|
||||
#undef HAVE_BP_SYM_H
|
||||
|
||||
/* Define to 1 if you have the `canonicalize_file_name' function. */
|
||||
#undef HAVE_CANONICALIZE_FILE_NAME
|
||||
|
||||
/* Define to 1 if you have the `chmod' function. */
|
||||
#undef HAVE_CHMOD
|
||||
|
||||
/* Define to 1 if you have the declaration of `memmem', and to 0 if you don't.
|
||||
*/
|
||||
#undef HAVE_DECL_MEMMEM
|
||||
|
||||
/* Define this if /dev/zero is readable device */
|
||||
#undef HAVE_DEV_ZERO
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
/* Define to 1 if you have the `fchmod' function. */
|
||||
#undef HAVE_FCHMOD
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#undef HAVE_FORK
|
||||
|
||||
/* Define to 1 if you have the `fstat' function. */
|
||||
#undef HAVE_FSTAT
|
||||
|
||||
/* Enable the GDBM library */
|
||||
#undef HAVE_GDBM
|
||||
|
||||
/* Define to 1 if the system has the type `int16_t'. */
|
||||
#undef HAVE_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `int32_t'. */
|
||||
#undef HAVE_INT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `int8_t'. */
|
||||
#undef HAVE_INT8_T
|
||||
|
||||
/* Define to 1 if the system has the type `intptr_t'. */
|
||||
#undef HAVE_INTPTR_T
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `gen' library (-lgen). */
|
||||
#undef HAVE_LIBGEN
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#undef HAVE_LIBGEN_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if the system has the type 'long long int'. */
|
||||
#undef HAVE_LONG_LONG_INT
|
||||
|
||||
@@ -47,9 +108,24 @@
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the `mprotect' function. */
|
||||
#undef HAVE_MPROTECT
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define this if pathfind(3) works */
|
||||
#undef HAVE_PATHFIND
|
||||
|
||||
/* Define to 1 if the system has the type `pid_t'. */
|
||||
#undef HAVE_PID_T
|
||||
|
||||
/* Define to 1 if ffsl is declared even after undefining macros. */
|
||||
#undef HAVE_RAW_DECL_FFSL
|
||||
|
||||
@@ -110,6 +186,15 @@
|
||||
/* Define to 1 if strverscmp is declared even after undefining macros. */
|
||||
#undef HAVE_RAW_DECL_STRVERSCMP
|
||||
|
||||
/* Define this if we have a functional realpath(3C) */
|
||||
#undef HAVE_REALPATH
|
||||
|
||||
/* Define to 1 if you have the <runetype.h> header file. */
|
||||
#undef HAVE_RUNETYPE_H
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#undef HAVE_SETJMP_H
|
||||
|
||||
/* Define to 1 if 'sig_atomic_t' is a signed integer type. */
|
||||
#undef HAVE_SIGNED_SIG_ATOMIC_T
|
||||
|
||||
@@ -119,48 +204,164 @@
|
||||
/* Define to 1 if 'wint_t' is a signed integer type. */
|
||||
#undef HAVE_SIGNED_WINT_T
|
||||
|
||||
/* Define to 1 if the system has the type `size_t'. */
|
||||
#undef HAVE_SIZE_T
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#undef HAVE_STDARG_H
|
||||
|
||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
||||
#undef HAVE_STDBOOL_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define this if strftime() works */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#undef HAVE_STRRCHR
|
||||
|
||||
/* Define to 1 if you have the `strsignal' function. */
|
||||
#undef HAVE_STRSIGNAL
|
||||
|
||||
/* Define to 1 if you have the <sysexits.h> header file. */
|
||||
#undef HAVE_SYSEXITS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/bitypes.h> header file. */
|
||||
#undef HAVE_SYS_BITYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/inttypes.h> header file. */
|
||||
#undef HAVE_SYS_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/limits.h> header file. */
|
||||
#undef HAVE_SYS_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/poll.h> header file. */
|
||||
#undef HAVE_SYS_POLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/procset.h> header file. */
|
||||
#undef HAVE_SYS_PROCSET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stropts.h> header file. */
|
||||
#undef HAVE_SYS_STROPTS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#undef HAVE_SYS_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||
#undef HAVE_SYS_UN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#undef HAVE_UINT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#undef HAVE_UINT8_T
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#undef HAVE_UINTPTR_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint_t'. */
|
||||
#undef HAVE_UINT_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if the system has the type 'unsigned long long int'. */
|
||||
#undef HAVE_UNSIGNED_LONG_LONG_INT
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to 1 if you have the <values.h> header file. */
|
||||
#undef HAVE_VALUES_H
|
||||
|
||||
/* Define to 1 if you have the <varargs.h> header file. */
|
||||
#undef HAVE_VARARGS_H
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#undef HAVE_VFORK
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
/* Define if you have the 'wchar_t' type. */
|
||||
/* Define to 1 if the system has the type `wchar_t'. */
|
||||
#undef HAVE_WCHAR_T
|
||||
|
||||
/* Define to 1 if the system has the type `wint_t'. */
|
||||
#undef HAVE_WINT_T
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
#undef HAVE_WORKING_FORK
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#undef HAVE_WORKING_VFORK
|
||||
|
||||
/* Define to a substitute value for mmap()'s MAP_ANONYMOUS flag. */
|
||||
#undef MAP_ANONYMOUS
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define this if optional arguments are disallowed */
|
||||
#undef NO_OPTIONAL_OPT_ARGS
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
@@ -182,14 +383,32 @@
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* define to a working POSIX compliant shell */
|
||||
#undef POSIX_SHELL
|
||||
|
||||
/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
|
||||
'ptrdiff_t'. */
|
||||
#undef PTRDIFF_T_SUFFIX
|
||||
|
||||
/* name of regex header file */
|
||||
#undef REGEX_HEADER
|
||||
|
||||
/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
|
||||
'sig_atomic_t'. */
|
||||
#undef SIG_ATOMIC_T_SUFFIX
|
||||
|
||||
/* The size of `char*', as computed by sizeof. */
|
||||
#undef SIZEOF_CHARP
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#undef SIZEOF_SHORT
|
||||
|
||||
/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
|
||||
'size_t'. */
|
||||
#undef SIZE_T_SUFFIX
|
||||
@@ -208,6 +427,9 @@
|
||||
'wint_t'. */
|
||||
#undef WINT_T_SUFFIX
|
||||
|
||||
/* Define this if a working libregex can be found */
|
||||
#undef WITH_LIBREGEX
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
@@ -271,6 +493,9 @@
|
||||
# define __GNUC_STDC_INLINE__ 1
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define to the equivalent of the C99 'restrict' keyword, or to
|
||||
nothing if this is not supported. Do not define if restrict is
|
||||
supported directly. */
|
||||
@@ -311,3 +536,6 @@
|
||||
# define _GL_ATTRIBUTE_CONST /* empty */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
#undef vfork
|
||||
|
||||
@@ -10,6 +10,8 @@ AC_CONFIG_HEADERS([config.h])
|
||||
AC_PROG_CC
|
||||
gl_EARLY
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.0.0])
|
||||
|
||||
LIBS="$oldlibs -lgdbm"
|
||||
@@ -31,6 +33,10 @@ LIBS="$oldlibs"
|
||||
|
||||
gl_INIT
|
||||
|
||||
enable_local_libopts=yes
|
||||
NEED_LIBOPTS_DIR=true
|
||||
LIBOPTS_CHECK([libopts])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
copyright (c) by Bruce Korb - all rights reserved
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> copyright (c) by Bruce Korb - all rights reserved
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,26 @@
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
3. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,26 @@
|
||||
## LIBOPTS Makefile
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
noinst_LIBRARIES = libopts.a
|
||||
|
||||
libopts_a_SOURCES = libopts.c
|
||||
libopts_a_CPPFLAGS = -I$(top_srcdir)
|
||||
EXTRA_DIST = \
|
||||
ag-char-map.h alias.c ao-strs.c \
|
||||
ao-strs.h autoopts/options.h autoopts/project.h \
|
||||
autoopts/usage-txt.h autoopts.c autoopts.h \
|
||||
boolean.c check.c compat/strchr.c \
|
||||
compat/pathfind.c compat/strdup.c compat/windows-config.h \
|
||||
compat/snprintf.c compat/compat.h configfile.c \
|
||||
cook.c COPYING.gplv3 COPYING.lgplv3 \
|
||||
COPYING.mbsd enum.c env.c \
|
||||
file.c find.c genshell.c \
|
||||
genshell.h load.c m4/liboptschk.m4 \
|
||||
m4/libopts.m4 MakeDefs.inc makeshell.c \
|
||||
nested.c numeric.c parse-duration.c \
|
||||
parse-duration.h pgusage.c proto.h \
|
||||
putshell.c README reset.c \
|
||||
restore.c save.c sort.c \
|
||||
stack.c streqvcmp.c text_mmap.c \
|
||||
time.c tokenize.c usage.c \
|
||||
value-type.c value-type.h version.c \
|
||||
xat-attribute.c xat-attribute.h
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
THIS TARBALL IS NOT A FULL DISTRIBUTION.
|
||||
|
||||
The contents of this tarball is designed to be incorporated into
|
||||
software packages that utilize the AutoOpts option automation package
|
||||
and are intended to be installed on systems that may not have libopts
|
||||
installed. It is redistributable under the terms of either the LGPL
|
||||
(see COPYING.lgpl) or under the terms of the advertising clause free BSD
|
||||
license (see COPYING.mbsd).
|
||||
|
||||
Usage Instructions for autoconf/automake/libtoolized projects:
|
||||
|
||||
1. Install the unrolled tarball into your package source tree,
|
||||
copying ``libopts.m4'' to your autoconf macro directory.
|
||||
|
||||
In your bootstrap (pre-configure) script, you can do this:
|
||||
|
||||
rm -rf libopts libopts-*
|
||||
gunzip -c `autoopts-config libsrc` | tar -xvf -
|
||||
mv -f libopts-*.*.* libopts
|
||||
cp -fp libopts/m4/*.m4 m4/.
|
||||
|
||||
I tend to put my configure auxiliary files in "m4".
|
||||
Whatever directory you choose, if it is not ".", then
|
||||
be sure to tell autoconf about it with:
|
||||
|
||||
AC_CONFIG_AUX_DIR(m4)
|
||||
|
||||
This is one macro where you *MUST* remember to *NOT* quote
|
||||
the argument. If you do, automake will get lost.
|
||||
|
||||
2. Add an invocation of either LIBOPTS_CHECK or LIBOPTS_CHECK_NOBUILD
|
||||
to your configure.ac file. See LIBOPTS_CHECK: below for details.
|
||||
|
||||
3. Add the following to your top level ``Makefile.am'' file:
|
||||
|
||||
if NEED_LIBOPTS
|
||||
SUBDIRS += $(LIBOPTS_DIR)
|
||||
endif
|
||||
|
||||
where ``<...>'' can be whatever other files or directories you may
|
||||
need. The SUBDIRS must be properly ordered. *PLEASE NOTE* it is
|
||||
crucial that the SUBDIRS be set under the control of an automake
|
||||
conditional. To work correctly, automake has to know the range of
|
||||
possible values of SUBDIRS. It's a magical name with magical
|
||||
properties. ``NEED_LIBOPTS'' will be correctly set by the
|
||||
``LIBOPTS_CHECK'' macro, above.
|
||||
|
||||
4. Add ``$(LIBOPTS_CFLAGS)'' to relevant compiler flags and
|
||||
``$(LIBOPTS_LDADD)'' to relevant link options whereever
|
||||
you need them in your build tree.
|
||||
|
||||
5. Make sure your object files explicitly depend upon the
|
||||
generated options header file. e.g.:
|
||||
|
||||
$(prog_OBJECTS) : prog-opts.h
|
||||
prog-opts.h : prog-opts.c
|
||||
prog-opts.c : prog-opts.def
|
||||
autogen prog-opts.def
|
||||
|
||||
6. *OPTIONAL* --
|
||||
If you are creating man pages and texi documentation from
|
||||
the program options, you will need these rules somewhere, too:
|
||||
|
||||
man_MANS = prog.1
|
||||
prog.1 : prog-opts.def
|
||||
autogen -Tagman-cmd.tpl -bprog prog-opts.def
|
||||
|
||||
invoke-prog.texi : prog-opts.def
|
||||
autogen -Tagtexi-cmd.tpl prog-opts.def
|
||||
|
||||
If your package does not utilize the auto* tools, then you
|
||||
will need to hand craft the rules for building the library.
|
||||
|
||||
LIBOPTS_CHECK:
|
||||
|
||||
The arguments to both macro are a relative path to the directory with
|
||||
the libopts source code. It is optional and defaults to "libopts".
|
||||
These macros work as follows:
|
||||
|
||||
1. LIBOPTS_CHECK([libopts/rel/path/optional])
|
||||
|
||||
Adds two command-line options to the generated configure script,
|
||||
--enable-local-libopts and --disable-libopts-install. AC_SUBST's
|
||||
LIBOPTS_CFLAGS, LIBOPTS_LDADD, and LIBOPTS_DIR for use in
|
||||
Makefile.am files. Adds Automake conditional NEED_LIBOPTS which
|
||||
will be true when the local copy of libopts should be built. Uses
|
||||
AC_CONFIG_FILES([$libopts-dir/Makefile]) to cause the local libopts
|
||||
into the package build. If the optional relative path to libopts is
|
||||
not provided, it defaults to simply "libopts".
|
||||
|
||||
2. LIBOPTS_CHECK_NOBUILD([libopts/rel/path/optional])
|
||||
|
||||
This variant of LIBOPTS_CHECK is useful when multiple configure.ac
|
||||
files in a package make use of a single libopts tearoff. In that
|
||||
case, only one of the configure.ac files should build libopts and
|
||||
others should simply use it. Consider this package arrangment:
|
||||
|
||||
all-tools/
|
||||
configure.ac
|
||||
common-tools/
|
||||
configure.ac
|
||||
libopts/
|
||||
|
||||
The parent package all-tools contains a subpackage common-tools
|
||||
which can be torn off and used independently. Programs configured
|
||||
by both configure.ac files link against the common-tools/libopts
|
||||
tearoff, when not using the system's libopts. The top-level
|
||||
configure.ac uses LIBOPTS_CHECK_NOBUILD([common-tools/libopts]),
|
||||
while common-tools/configure.ac uses LIBOPTS_CHECK. The difference
|
||||
is LIBOPTS_CHECK_NOBUILD will never build the libopts tearoff,
|
||||
leaving that to the subpackage configure.ac's LIBOPTS_CHECK.
|
||||
Specifically, LIBOPTS_CHECK_NOBUILD always results in the
|
||||
NEED_LIBOPTS Automake conditional being false, and does not invoke
|
||||
AC_CONFIG_FILES(path-to-libopts/Makefile).
|
||||
|
||||
LICENSING:
|
||||
|
||||
This material is Copyright (c) 1992-2012 by Bruce Korb. You are
|
||||
licensed to use this under the terms of either the GNU Lesser General
|
||||
Public License (see: COPYING.lgpl), or, at your option, the modified
|
||||
Berkeley Software Distribution License (see: COPYING.mbsd). Both of
|
||||
these files should be included with this tarball.
|
||||
@@ -0,0 +1,491 @@
|
||||
/*
|
||||
* 28 bits for 44 character classifications
|
||||
* generated by char-mapper on 05/06/12 at 16:20:58
|
||||
*
|
||||
* This file contains the character classifications
|
||||
* used by AutoGen and AutoOpts for identifying tokens.
|
||||
* The table is static scope, so %guard is empty.
|
||||
*
|
||||
* This file is part of AutoGen.
|
||||
* Copyright (c) 1992-2012 Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoGen is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* AutoGen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef AG_CHAR_MAP_H_GUARD
|
||||
#define AG_CHAR_MAP_H_GUARD 1
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# if defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
|
||||
# elif defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
|
||||
# elif !defined(HAVE_UINT32_T)
|
||||
# if SIZEOF_INT == 4
|
||||
typedef unsigned int uint32_t;
|
||||
# elif SIZEOF_LONG == 4
|
||||
typedef unsigned long uint32_t;
|
||||
# endif
|
||||
# endif /* HAVE_*INT*_H header */
|
||||
|
||||
#else /* not HAVE_CONFIG_H -- */
|
||||
# include <inttypes.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#if 0 /* mapping specification source (from autogen.map) */
|
||||
//
|
||||
// %guard
|
||||
// %file ag-char-map.h
|
||||
// %backup
|
||||
// %optimize
|
||||
//
|
||||
// %comment -- see above
|
||||
// %
|
||||
//
|
||||
// newline "\n"
|
||||
// nul-byte "\x00"
|
||||
// dir-sep "/\\"
|
||||
// percent "%"
|
||||
// comma ","
|
||||
// colon ":"
|
||||
// underscore "_"
|
||||
// plus "+"
|
||||
// dollar "$"
|
||||
//
|
||||
// horiz-white "\t "
|
||||
// alt-white "\v\f\r\b"
|
||||
// whitespace +horiz-white +newline +alt-white
|
||||
// non-nl-white +horiz-white +alt-white
|
||||
// quote "'\""
|
||||
// parentheses "()"
|
||||
//
|
||||
// graphic "!-~"
|
||||
// inversion "~-"
|
||||
// oct-digit "0-7"
|
||||
// dec-digit "89" +oct-digit
|
||||
// hex-digit "a-fA-F" +dec-digit
|
||||
// lower-case "a-z"
|
||||
// upper-case "A-Z"
|
||||
// alphabetic +lower-case +upper-case
|
||||
// alphanumeric +alphabetic +dec-digit
|
||||
// var-first +underscore +alphabetic
|
||||
// variable-name +var-first +dec-digit
|
||||
// option-name "^-" +variable-name
|
||||
// value-name +colon +option-name
|
||||
// name-sep "[.]"
|
||||
// compound-name +value-name +name-sep +horiz-white
|
||||
// scheme-note +parentheses +quote
|
||||
//
|
||||
// unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses
|
||||
// end-xml-token "/>" +whitespace
|
||||
// plus-n-space +plus +whitespace
|
||||
// punctuation "!-~" -alphanumeric -"_"
|
||||
// suffix "-._" +alphanumeric
|
||||
// suffix-fmt +percent +suffix +dir-sep
|
||||
// false-type "nNfF0" +nul-byte
|
||||
// file-name +dir-sep +suffix
|
||||
// end-token +nul-byte +whitespace
|
||||
// end-list-entry +comma +end-token
|
||||
// set-separator "|+" +end-list-entry
|
||||
// signed-number +inversion +dec-digit
|
||||
// make-script +dollar +newline
|
||||
//
|
||||
#endif /* 0 -- mapping spec. source */
|
||||
|
||||
|
||||
typedef uint32_t ag_char_map_mask_t;
|
||||
|
||||
#define IS_NEWLINE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000001)
|
||||
#define SPN_NEWLINE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 0)
|
||||
#define BRK_NEWLINE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 0)
|
||||
#define SPN_NEWLINE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 0)
|
||||
#define BRK_NEWLINE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 0)
|
||||
#define IS_NUL_BYTE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000002)
|
||||
#define SPN_NUL_BYTE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 1)
|
||||
#define BRK_NUL_BYTE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 1)
|
||||
#define SPN_NUL_BYTE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 1)
|
||||
#define BRK_NUL_BYTE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 1)
|
||||
#define IS_DIR_SEP_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000004)
|
||||
#define SPN_DIR_SEP_CHARS(_s) spn_ag_char_map_chars((char *)_s, 2)
|
||||
#define BRK_DIR_SEP_CHARS(_s) brk_ag_char_map_chars((char *)_s, 2)
|
||||
#define SPN_DIR_SEP_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 2)
|
||||
#define BRK_DIR_SEP_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 2)
|
||||
#define IS_PERCENT_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000008)
|
||||
#define SPN_PERCENT_CHARS(_s) spn_ag_char_map_chars((char *)_s, 3)
|
||||
#define BRK_PERCENT_CHARS(_s) brk_ag_char_map_chars((char *)_s, 3)
|
||||
#define SPN_PERCENT_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 3)
|
||||
#define BRK_PERCENT_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 3)
|
||||
#define IS_COMMA_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000010)
|
||||
#define SPN_COMMA_CHARS(_s) spn_ag_char_map_chars((char *)_s, 4)
|
||||
#define BRK_COMMA_CHARS(_s) brk_ag_char_map_chars((char *)_s, 4)
|
||||
#define SPN_COMMA_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 4)
|
||||
#define BRK_COMMA_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 4)
|
||||
#define IS_COLON_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000020)
|
||||
#define SPN_COLON_CHARS(_s) spn_ag_char_map_chars((char *)_s, 5)
|
||||
#define BRK_COLON_CHARS(_s) brk_ag_char_map_chars((char *)_s, 5)
|
||||
#define SPN_COLON_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 5)
|
||||
#define BRK_COLON_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 5)
|
||||
#define IS_UNDERSCORE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000040)
|
||||
#define SPN_UNDERSCORE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 6)
|
||||
#define BRK_UNDERSCORE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 6)
|
||||
#define SPN_UNDERSCORE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 6)
|
||||
#define BRK_UNDERSCORE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 6)
|
||||
#define IS_PLUS_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000080)
|
||||
#define SPN_PLUS_CHARS(_s) spn_ag_char_map_chars((char *)_s, 7)
|
||||
#define BRK_PLUS_CHARS(_s) brk_ag_char_map_chars((char *)_s, 7)
|
||||
#define SPN_PLUS_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 7)
|
||||
#define BRK_PLUS_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 7)
|
||||
#define IS_DOLLAR_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000100)
|
||||
#define SPN_DOLLAR_CHARS(_s) spn_ag_char_map_chars((char *)_s, 8)
|
||||
#define BRK_DOLLAR_CHARS(_s) brk_ag_char_map_chars((char *)_s, 8)
|
||||
#define SPN_DOLLAR_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 8)
|
||||
#define BRK_DOLLAR_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 8)
|
||||
#define IS_HORIZ_WHITE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000200)
|
||||
#define SPN_HORIZ_WHITE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 9)
|
||||
#define BRK_HORIZ_WHITE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 9)
|
||||
#define SPN_HORIZ_WHITE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 9)
|
||||
#define BRK_HORIZ_WHITE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 9)
|
||||
#define IS_ALT_WHITE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000400)
|
||||
#define SPN_ALT_WHITE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 10)
|
||||
#define BRK_ALT_WHITE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 10)
|
||||
#define SPN_ALT_WHITE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 10)
|
||||
#define BRK_ALT_WHITE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 10)
|
||||
#define IS_WHITESPACE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000601)
|
||||
#define SPN_WHITESPACE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 11)
|
||||
#define BRK_WHITESPACE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 11)
|
||||
#define SPN_WHITESPACE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 11)
|
||||
#define BRK_WHITESPACE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 11)
|
||||
#define IS_NON_NL_WHITE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000600)
|
||||
#define SPN_NON_NL_WHITE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 12)
|
||||
#define BRK_NON_NL_WHITE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 12)
|
||||
#define SPN_NON_NL_WHITE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 12)
|
||||
#define BRK_NON_NL_WHITE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 12)
|
||||
#define IS_QUOTE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000800)
|
||||
#define SPN_QUOTE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 13)
|
||||
#define BRK_QUOTE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 13)
|
||||
#define SPN_QUOTE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 13)
|
||||
#define BRK_QUOTE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 13)
|
||||
#define IS_PARENTHESES_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0001000)
|
||||
#define SPN_PARENTHESES_CHARS(_s) spn_ag_char_map_chars((char *)_s, 14)
|
||||
#define BRK_PARENTHESES_CHARS(_s) brk_ag_char_map_chars((char *)_s, 14)
|
||||
#define SPN_PARENTHESES_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 14)
|
||||
#define BRK_PARENTHESES_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 14)
|
||||
#define IS_GRAPHIC_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0002000)
|
||||
#define SPN_GRAPHIC_CHARS(_s) spn_ag_char_map_chars((char *)_s, 15)
|
||||
#define BRK_GRAPHIC_CHARS(_s) brk_ag_char_map_chars((char *)_s, 15)
|
||||
#define SPN_GRAPHIC_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 15)
|
||||
#define BRK_GRAPHIC_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 15)
|
||||
#define IS_INVERSION_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0004000)
|
||||
#define SPN_INVERSION_CHARS(_s) spn_ag_char_map_chars((char *)_s, 16)
|
||||
#define BRK_INVERSION_CHARS(_s) brk_ag_char_map_chars((char *)_s, 16)
|
||||
#define SPN_INVERSION_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 16)
|
||||
#define BRK_INVERSION_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 16)
|
||||
#define IS_OCT_DIGIT_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0008000)
|
||||
#define SPN_OCT_DIGIT_CHARS(_s) spn_ag_char_map_chars((char *)_s, 17)
|
||||
#define BRK_OCT_DIGIT_CHARS(_s) brk_ag_char_map_chars((char *)_s, 17)
|
||||
#define SPN_OCT_DIGIT_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 17)
|
||||
#define BRK_OCT_DIGIT_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 17)
|
||||
#define IS_DEC_DIGIT_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0018000)
|
||||
#define SPN_DEC_DIGIT_CHARS(_s) spn_ag_char_map_chars((char *)_s, 18)
|
||||
#define BRK_DEC_DIGIT_CHARS(_s) brk_ag_char_map_chars((char *)_s, 18)
|
||||
#define SPN_DEC_DIGIT_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 18)
|
||||
#define BRK_DEC_DIGIT_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 18)
|
||||
#define IS_HEX_DIGIT_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0038000)
|
||||
#define SPN_HEX_DIGIT_CHARS(_s) spn_ag_char_map_chars((char *)_s, 19)
|
||||
#define BRK_HEX_DIGIT_CHARS(_s) brk_ag_char_map_chars((char *)_s, 19)
|
||||
#define SPN_HEX_DIGIT_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 19)
|
||||
#define BRK_HEX_DIGIT_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 19)
|
||||
#define IS_LOWER_CASE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0040000)
|
||||
#define SPN_LOWER_CASE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 20)
|
||||
#define BRK_LOWER_CASE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 20)
|
||||
#define SPN_LOWER_CASE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 20)
|
||||
#define BRK_LOWER_CASE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 20)
|
||||
#define IS_UPPER_CASE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0080000)
|
||||
#define SPN_UPPER_CASE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 21)
|
||||
#define BRK_UPPER_CASE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 21)
|
||||
#define SPN_UPPER_CASE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 21)
|
||||
#define BRK_UPPER_CASE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 21)
|
||||
#define IS_ALPHABETIC_CHAR( _c) is_ag_char_map_char((char)( _c), 0x00C0000)
|
||||
#define SPN_ALPHABETIC_CHARS(_s) spn_ag_char_map_chars((char *)_s, 22)
|
||||
#define BRK_ALPHABETIC_CHARS(_s) brk_ag_char_map_chars((char *)_s, 22)
|
||||
#define SPN_ALPHABETIC_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 22)
|
||||
#define BRK_ALPHABETIC_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 22)
|
||||
#define IS_ALPHANUMERIC_CHAR( _c) is_ag_char_map_char((char)( _c), 0x00D8000)
|
||||
#define SPN_ALPHANUMERIC_CHARS(_s) spn_ag_char_map_chars((char *)_s, 23)
|
||||
#define BRK_ALPHANUMERIC_CHARS(_s) brk_ag_char_map_chars((char *)_s, 23)
|
||||
#define SPN_ALPHANUMERIC_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 23)
|
||||
#define BRK_ALPHANUMERIC_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 23)
|
||||
#define IS_VAR_FIRST_CHAR( _c) is_ag_char_map_char((char)( _c), 0x00C0040)
|
||||
#define SPN_VAR_FIRST_CHARS(_s) spn_ag_char_map_chars((char *)_s, 24)
|
||||
#define BRK_VAR_FIRST_CHARS(_s) brk_ag_char_map_chars((char *)_s, 24)
|
||||
#define SPN_VAR_FIRST_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 24)
|
||||
#define BRK_VAR_FIRST_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 24)
|
||||
#define IS_VARIABLE_NAME_CHAR( _c) is_ag_char_map_char((char)( _c), 0x00D8040)
|
||||
#define SPN_VARIABLE_NAME_CHARS(_s) spn_ag_char_map_chars((char *)_s, 25)
|
||||
#define BRK_VARIABLE_NAME_CHARS(_s) brk_ag_char_map_chars((char *)_s, 25)
|
||||
#define SPN_VARIABLE_NAME_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 25)
|
||||
#define BRK_VARIABLE_NAME_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 25)
|
||||
#define IS_OPTION_NAME_CHAR( _c) is_ag_char_map_char((char)( _c), 0x01D8040)
|
||||
#define SPN_OPTION_NAME_CHARS(_s) spn_ag_char_map_chars((char *)_s, 26)
|
||||
#define BRK_OPTION_NAME_CHARS(_s) brk_ag_char_map_chars((char *)_s, 26)
|
||||
#define SPN_OPTION_NAME_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 26)
|
||||
#define BRK_OPTION_NAME_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 26)
|
||||
#define IS_VALUE_NAME_CHAR( _c) is_ag_char_map_char((char)( _c), 0x01D8060)
|
||||
#define SPN_VALUE_NAME_CHARS(_s) spn_ag_char_map_chars((char *)_s, 27)
|
||||
#define BRK_VALUE_NAME_CHARS(_s) brk_ag_char_map_chars((char *)_s, 27)
|
||||
#define SPN_VALUE_NAME_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 27)
|
||||
#define BRK_VALUE_NAME_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 27)
|
||||
#define IS_NAME_SEP_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0200000)
|
||||
#define SPN_NAME_SEP_CHARS(_s) spn_ag_char_map_chars((char *)_s, 28)
|
||||
#define BRK_NAME_SEP_CHARS(_s) brk_ag_char_map_chars((char *)_s, 28)
|
||||
#define SPN_NAME_SEP_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 28)
|
||||
#define BRK_NAME_SEP_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 28)
|
||||
#define IS_COMPOUND_NAME_CHAR( _c) is_ag_char_map_char((char)( _c), 0x03D8260)
|
||||
#define SPN_COMPOUND_NAME_CHARS(_s) spn_ag_char_map_chars((char *)_s, 29)
|
||||
#define BRK_COMPOUND_NAME_CHARS(_s) brk_ag_char_map_chars((char *)_s, 29)
|
||||
#define SPN_COMPOUND_NAME_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 29)
|
||||
#define BRK_COMPOUND_NAME_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 29)
|
||||
#define IS_SCHEME_NOTE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0001800)
|
||||
#define SPN_SCHEME_NOTE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 30)
|
||||
#define BRK_SCHEME_NOTE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 30)
|
||||
#define SPN_SCHEME_NOTE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 30)
|
||||
#define BRK_SCHEME_NOTE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 30)
|
||||
#define IS_UNQUOTABLE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0400000)
|
||||
#define SPN_UNQUOTABLE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 31)
|
||||
#define BRK_UNQUOTABLE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 31)
|
||||
#define SPN_UNQUOTABLE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 31)
|
||||
#define BRK_UNQUOTABLE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 31)
|
||||
#define IS_END_XML_TOKEN_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0800601)
|
||||
#define SPN_END_XML_TOKEN_CHARS(_s) spn_ag_char_map_chars((char *)_s, 32)
|
||||
#define BRK_END_XML_TOKEN_CHARS(_s) brk_ag_char_map_chars((char *)_s, 32)
|
||||
#define SPN_END_XML_TOKEN_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 32)
|
||||
#define BRK_END_XML_TOKEN_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 32)
|
||||
#define IS_PLUS_N_SPACE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000681)
|
||||
#define SPN_PLUS_N_SPACE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 33)
|
||||
#define BRK_PLUS_N_SPACE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 33)
|
||||
#define SPN_PLUS_N_SPACE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 33)
|
||||
#define BRK_PLUS_N_SPACE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 33)
|
||||
#define IS_PUNCTUATION_CHAR( _c) is_ag_char_map_char((char)( _c), 0x1000000)
|
||||
#define SPN_PUNCTUATION_CHARS(_s) spn_ag_char_map_chars((char *)_s, 34)
|
||||
#define BRK_PUNCTUATION_CHARS(_s) brk_ag_char_map_chars((char *)_s, 34)
|
||||
#define SPN_PUNCTUATION_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 34)
|
||||
#define BRK_PUNCTUATION_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 34)
|
||||
#define IS_SUFFIX_CHAR( _c) is_ag_char_map_char((char)( _c), 0x20D8000)
|
||||
#define SPN_SUFFIX_CHARS(_s) spn_ag_char_map_chars((char *)_s, 35)
|
||||
#define BRK_SUFFIX_CHARS(_s) brk_ag_char_map_chars((char *)_s, 35)
|
||||
#define SPN_SUFFIX_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 35)
|
||||
#define BRK_SUFFIX_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 35)
|
||||
#define IS_SUFFIX_FMT_CHAR( _c) is_ag_char_map_char((char)( _c), 0x20D800C)
|
||||
#define SPN_SUFFIX_FMT_CHARS(_s) spn_ag_char_map_chars((char *)_s, 36)
|
||||
#define BRK_SUFFIX_FMT_CHARS(_s) brk_ag_char_map_chars((char *)_s, 36)
|
||||
#define SPN_SUFFIX_FMT_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 36)
|
||||
#define BRK_SUFFIX_FMT_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 36)
|
||||
#define IS_FALSE_TYPE_CHAR( _c) is_ag_char_map_char((char)( _c), 0x4000002)
|
||||
#define SPN_FALSE_TYPE_CHARS(_s) spn_ag_char_map_chars((char *)_s, 37)
|
||||
#define BRK_FALSE_TYPE_CHARS(_s) brk_ag_char_map_chars((char *)_s, 37)
|
||||
#define SPN_FALSE_TYPE_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 37)
|
||||
#define BRK_FALSE_TYPE_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 37)
|
||||
#define IS_FILE_NAME_CHAR( _c) is_ag_char_map_char((char)( _c), 0x20D8004)
|
||||
#define SPN_FILE_NAME_CHARS(_s) spn_ag_char_map_chars((char *)_s, 38)
|
||||
#define BRK_FILE_NAME_CHARS(_s) brk_ag_char_map_chars((char *)_s, 38)
|
||||
#define SPN_FILE_NAME_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 38)
|
||||
#define BRK_FILE_NAME_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 38)
|
||||
#define IS_END_TOKEN_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000603)
|
||||
#define SPN_END_TOKEN_CHARS(_s) spn_ag_char_map_chars((char *)_s, 39)
|
||||
#define BRK_END_TOKEN_CHARS(_s) brk_ag_char_map_chars((char *)_s, 39)
|
||||
#define SPN_END_TOKEN_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 39)
|
||||
#define BRK_END_TOKEN_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 39)
|
||||
#define IS_END_LIST_ENTRY_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000613)
|
||||
#define SPN_END_LIST_ENTRY_CHARS(_s) spn_ag_char_map_chars((char *)_s, 40)
|
||||
#define BRK_END_LIST_ENTRY_CHARS(_s) brk_ag_char_map_chars((char *)_s, 40)
|
||||
#define SPN_END_LIST_ENTRY_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 40)
|
||||
#define BRK_END_LIST_ENTRY_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 40)
|
||||
#define IS_SET_SEPARATOR_CHAR( _c) is_ag_char_map_char((char)( _c), 0x8000613)
|
||||
#define SPN_SET_SEPARATOR_CHARS(_s) spn_ag_char_map_chars((char *)_s, 41)
|
||||
#define BRK_SET_SEPARATOR_CHARS(_s) brk_ag_char_map_chars((char *)_s, 41)
|
||||
#define SPN_SET_SEPARATOR_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 41)
|
||||
#define BRK_SET_SEPARATOR_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 41)
|
||||
#define IS_SIGNED_NUMBER_CHAR( _c) is_ag_char_map_char((char)( _c), 0x001C000)
|
||||
#define SPN_SIGNED_NUMBER_CHARS(_s) spn_ag_char_map_chars((char *)_s, 42)
|
||||
#define BRK_SIGNED_NUMBER_CHARS(_s) brk_ag_char_map_chars((char *)_s, 42)
|
||||
#define SPN_SIGNED_NUMBER_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 42)
|
||||
#define BRK_SIGNED_NUMBER_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 42)
|
||||
#define IS_MAKE_SCRIPT_CHAR( _c) is_ag_char_map_char((char)( _c), 0x0000101)
|
||||
#define SPN_MAKE_SCRIPT_CHARS(_s) spn_ag_char_map_chars((char *)_s, 43)
|
||||
#define BRK_MAKE_SCRIPT_CHARS(_s) brk_ag_char_map_chars((char *)_s, 43)
|
||||
#define SPN_MAKE_SCRIPT_BACK(s,e) spn_ag_char_map_back((char *)s, (char *)e, 43)
|
||||
#define BRK_MAKE_SCRIPT_BACK(s,e) brk_ag_char_map_back((char *)s, (char *)e, 43)
|
||||
|
||||
static ag_char_map_mask_t const ag_char_map_table[128] = {
|
||||
/*NUL*/ 0x0000002, /*x01*/ 0x0000000, /*x02*/ 0x0000000, /*x03*/ 0x0000000,
|
||||
/*x04*/ 0x0000000, /*x05*/ 0x0000000, /*x06*/ 0x0000000, /*BEL*/ 0x0000000,
|
||||
/* BS*/ 0x0000400, /* HT*/ 0x0000200, /* NL*/ 0x0000001, /* VT*/ 0x0000400,
|
||||
/* FF*/ 0x0000400, /* CR*/ 0x0000400, /*x0E*/ 0x0000000, /*x0F*/ 0x0000000,
|
||||
/*x10*/ 0x0000000, /*x11*/ 0x0000000, /*x12*/ 0x0000000, /*x13*/ 0x0000000,
|
||||
/*x14*/ 0x0000000, /*x15*/ 0x0000000, /*x16*/ 0x0000000, /*x17*/ 0x0000000,
|
||||
/*x18*/ 0x0000000, /*x19*/ 0x0000000, /*x1A*/ 0x0000000, /*ESC*/ 0x0000000,
|
||||
/*x1C*/ 0x0000000, /*x1D*/ 0x0000000, /*x1E*/ 0x0000000, /*x1F*/ 0x0000000,
|
||||
/* */ 0x0000200, /* ! */ 0x1402000, /* " */ 0x1002800, /* # */ 0x1002000,
|
||||
/* $ */ 0x1402100, /* % */ 0x1402008, /* & */ 0x1402000, /* ' */ 0x1002800,
|
||||
/* ( */ 0x1003000, /* ) */ 0x1003000, /* * */ 0x1002000, /* + */ 0x9402080,
|
||||
/* , */ 0x1002010, /* - */ 0x3506000, /* . */ 0x3602000, /* / */ 0x1C02004,
|
||||
/* 0 */ 0x440A000, /* 1 */ 0x040A000, /* 2 */ 0x040A000, /* 3 */ 0x040A000,
|
||||
/* 4 */ 0x040A000, /* 5 */ 0x040A000, /* 6 */ 0x040A000, /* 7 */ 0x040A000,
|
||||
/* 8 */ 0x0412000, /* 9 */ 0x0412000, /* : */ 0x1402020, /* ; */ 0x1002000,
|
||||
/* < */ 0x1002000, /* = */ 0x1002000, /* > */ 0x1802000, /* ? */ 0x1002000,
|
||||
/* @ */ 0x1402000, /* A */ 0x04A2000, /* B */ 0x04A2000, /* C */ 0x04A2000,
|
||||
/* D */ 0x04A2000, /* E */ 0x04A2000, /* F */ 0x44A2000, /* G */ 0x0482000,
|
||||
/* H */ 0x0482000, /* I */ 0x0482000, /* J */ 0x0482000, /* K */ 0x0482000,
|
||||
/* L */ 0x0482000, /* M */ 0x0482000, /* N */ 0x4482000, /* O */ 0x0482000,
|
||||
/* P */ 0x0482000, /* Q */ 0x0482000, /* R */ 0x0482000, /* S */ 0x0482000,
|
||||
/* T */ 0x0482000, /* U */ 0x0482000, /* V */ 0x0482000, /* W */ 0x0482000,
|
||||
/* X */ 0x0482000, /* Y */ 0x0482000, /* Z */ 0x0482000, /* [ */ 0x1202000,
|
||||
/* \ */ 0x1002004, /* ] */ 0x1202000, /* ^ */ 0x1502000, /* _ */ 0x2402040,
|
||||
/* ` */ 0x1002000, /* a */ 0x0462000, /* b */ 0x0462000, /* c */ 0x0462000,
|
||||
/* d */ 0x0462000, /* e */ 0x0462000, /* f */ 0x4462000, /* g */ 0x0442000,
|
||||
/* h */ 0x0442000, /* i */ 0x0442000, /* j */ 0x0442000, /* k */ 0x0442000,
|
||||
/* l */ 0x0442000, /* m */ 0x0442000, /* n */ 0x4442000, /* o */ 0x0442000,
|
||||
/* p */ 0x0442000, /* q */ 0x0442000, /* r */ 0x0442000, /* s */ 0x0442000,
|
||||
/* t */ 0x0442000, /* u */ 0x0442000, /* v */ 0x0442000, /* w */ 0x0442000,
|
||||
/* x */ 0x0442000, /* y */ 0x0442000, /* z */ 0x0442000, /* { */ 0x1002000,
|
||||
/* | */ 0x9402000, /* } */ 0x1002000, /* ~ */ 0x1406000, /*x7F*/ 0x0000000
|
||||
};
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static unsigned char const * ag_char_map_spanners[44];
|
||||
/**
|
||||
* Character category masks. Some categories may have multiple bits,
|
||||
* if their definition incorporates other character categories.
|
||||
* This mask array is only used by calc_ag_char_map_spanners().
|
||||
*/
|
||||
static ag_char_map_mask_t const ag_char_map_masks[44] = {
|
||||
0x0000001, /* NEWLINE */
|
||||
0x0000002, /* NUL_BYTE */
|
||||
0x0000004, /* DIR_SEP */
|
||||
0x0000008, /* PERCENT */
|
||||
0x0000010, /* COMMA */
|
||||
0x0000020, /* COLON */
|
||||
0x0000040, /* UNDERSCORE */
|
||||
0x0000080, /* PLUS */
|
||||
0x0000100, /* DOLLAR */
|
||||
0x0000200, /* HORIZ_WHITE */
|
||||
0x0000400, /* ALT_WHITE */
|
||||
0x0000601, /* WHITESPACE */
|
||||
0x0000600, /* NON_NL_WHITE */
|
||||
0x0000800, /* QUOTE */
|
||||
0x0001000, /* PARENTHESES */
|
||||
0x0002000, /* GRAPHIC */
|
||||
0x0004000, /* INVERSION */
|
||||
0x0008000, /* OCT_DIGIT */
|
||||
0x0018000, /* DEC_DIGIT */
|
||||
0x0038000, /* HEX_DIGIT */
|
||||
0x0040000, /* LOWER_CASE */
|
||||
0x0080000, /* UPPER_CASE */
|
||||
0x00C0000, /* ALPHABETIC */
|
||||
0x00D8000, /* ALPHANUMERIC */
|
||||
0x00C0040, /* VAR_FIRST */
|
||||
0x00D8040, /* VARIABLE_NAME */
|
||||
0x01D8040, /* OPTION_NAME */
|
||||
0x01D8060, /* VALUE_NAME */
|
||||
0x0200000, /* NAME_SEP */
|
||||
0x03D8260, /* COMPOUND_NAME */
|
||||
0x0001800, /* SCHEME_NOTE */
|
||||
0x0400000, /* UNQUOTABLE */
|
||||
0x0800601, /* END_XML_TOKEN */
|
||||
0x0000681, /* PLUS_N_SPACE */
|
||||
0x1000000, /* PUNCTUATION */
|
||||
0x20D8000, /* SUFFIX */
|
||||
0x20D800C, /* SUFFIX_FMT */
|
||||
0x4000002, /* FALSE_TYPE */
|
||||
0x20D8004, /* FILE_NAME */
|
||||
0x0000603, /* END_TOKEN */
|
||||
0x0000613, /* END_LIST_ENTRY */
|
||||
0x8000613, /* SET_SEPARATOR */
|
||||
0x001C000, /* SIGNED_NUMBER */
|
||||
0x0000101, /* MAKE_SCRIPT */
|
||||
};
|
||||
|
||||
#define lock_ag_char_map_spanners()
|
||||
#define unlock_ag_char_map_spanners()
|
||||
|
||||
static unsigned char const *
|
||||
calc_ag_char_map_spanners(unsigned int mask_ix)
|
||||
{
|
||||
lock_ag_char_map_spanners();
|
||||
if (ag_char_map_spanners[mask_ix] == NULL) {
|
||||
int ix = 1;
|
||||
ag_char_map_mask_t mask = ag_char_map_masks[mask_ix];
|
||||
unsigned char * res = malloc(256 /* 1 << NBBY */);
|
||||
memset(res, 0, 256);
|
||||
for (; ix < 128; ix++)
|
||||
if (ag_char_map_table[ix] & mask)
|
||||
res[ix] = 1;
|
||||
ag_char_map_spanners[mask_ix] = res;
|
||||
}
|
||||
unlock_ag_char_map_spanners();
|
||||
return ag_char_map_spanners[mask_ix];
|
||||
}
|
||||
#define ag_char_map_masks POISONED_ag_char_map_masks
|
||||
|
||||
static inline int
|
||||
is_ag_char_map_char(char ch, ag_char_map_mask_t mask)
|
||||
{
|
||||
unsigned int ix = (unsigned char)ch;
|
||||
return ((ix < 128) && ((ag_char_map_table[ix] & mask) != 0));
|
||||
}
|
||||
|
||||
static inline char *
|
||||
spn_ag_char_map_chars(char * p, unsigned int mask_ix)
|
||||
{
|
||||
unsigned char const * v = ag_char_map_spanners[mask_ix];
|
||||
if (v == NULL)
|
||||
v = calc_ag_char_map_spanners(mask_ix);
|
||||
while (v[(unsigned)*p]) p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
brk_ag_char_map_chars(char * p, unsigned int mask_ix)
|
||||
{
|
||||
unsigned char const * v = ag_char_map_spanners[mask_ix];
|
||||
if (v == NULL)
|
||||
v = calc_ag_char_map_spanners(mask_ix);
|
||||
while ((*p != '\0') && (! v[(unsigned)*p])) p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
spn_ag_char_map_back(char * s, char * e, unsigned int mask_ix)
|
||||
{
|
||||
unsigned char const * v = ag_char_map_spanners[mask_ix];
|
||||
if (v == NULL)
|
||||
v = calc_ag_char_map_spanners(mask_ix);
|
||||
if (s >= e) e = s + strlen(s);
|
||||
while ((e > s) && v[(unsigned)e[-1]]) e--;
|
||||
return e;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
brk_ag_char_map_back(char * s, char * e, unsigned int mask_ix)
|
||||
{
|
||||
unsigned char const * v = ag_char_map_spanners[mask_ix];
|
||||
if (v == NULL)
|
||||
v = calc_ag_char_map_spanners(mask_ix);
|
||||
if (s == e) e += strlen(e);
|
||||
while ((e > s) && (! v[(unsigned)e[-1]])) e--;
|
||||
return e;
|
||||
}
|
||||
#endif /* AG_CHAR_MAP_H_GUARD */
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
|
||||
/**
|
||||
* \file alias.c
|
||||
*
|
||||
* Time-stamp: "2012-02-12 09:41:42 bkorb"
|
||||
*
|
||||
* Automated Options Paged Usage module.
|
||||
*
|
||||
* This routine will forward an option alias to the correct option code.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*=export_func optionAlias
|
||||
* private:
|
||||
*
|
||||
* what: relay an option to its alias
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
* arg: + unsigned int + alias + the aliased-to option index +
|
||||
* ret-type: int
|
||||
*
|
||||
* doc:
|
||||
* Handle one option as if it had been specified as another. Exactly.
|
||||
* Returns "-1" if the aliased-to option has appeared too many times.
|
||||
=*/
|
||||
int
|
||||
optionAlias(tOptions * pOpts, tOptDesc * pOldOD, unsigned int alias)
|
||||
{
|
||||
tOptDesc * pOD;
|
||||
|
||||
if (pOpts == OPTPROC_EMIT_USAGE)
|
||||
return 0;
|
||||
|
||||
pOD = pOpts->pOptDesc + alias;
|
||||
if ((unsigned)pOpts->optCt <= alias) {
|
||||
fwrite(zAliasRange, strlen (zAliasRange), 1, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy over the option instance flags
|
||||
*/
|
||||
pOD->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
pOD->fOptState |= (pOldOD->fOptState & ~OPTST_PERSISTENT_MASK);
|
||||
pOD->optArg.argString = pOldOD->optArg.argString;
|
||||
|
||||
/*
|
||||
* Keep track of count only for DEFINED (command line) options.
|
||||
* IF we have too many, build up an error message and bail.
|
||||
*/
|
||||
if ( (pOD->fOptState & OPTST_DEFINED)
|
||||
&& (++pOD->optOccCt > pOD->optMaxCt) ) {
|
||||
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
char const * pzEqv =
|
||||
(pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil;
|
||||
|
||||
fputs(zErrOnly, stderr);
|
||||
|
||||
if (pOD->optMaxCt > 1)
|
||||
fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv);
|
||||
else
|
||||
fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the state bits and counters
|
||||
*/
|
||||
pOldOD->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
pOldOD->optOccCt = 0;
|
||||
|
||||
/*
|
||||
* If there is a procedure to call, call it
|
||||
*/
|
||||
if (pOD->pOptProc != NULL)
|
||||
(*pOD->pOptProc)(pOpts, pOD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/alias.c */
|
||||
@@ -0,0 +1,323 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ao-strs.c)
|
||||
*
|
||||
* It has been AutoGen-ed May 6, 2012 at 04:20:58 PM by AutoGen 5.16pre36
|
||||
* From the definitions ao-strs.def
|
||||
* and the template file strings
|
||||
*
|
||||
* Copyright (C) 2011-2012 Bruce Korb, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* Modified (3 clause) Berkeley Software Distribution License
|
||||
* <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name ``Bruce Korb'' nor the name of any other
|
||||
* contributor may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "ao-strs.h"
|
||||
|
||||
char const ao_strs_strtable[6266] =
|
||||
/* 0 */ " \t\n"
|
||||
":=\0"
|
||||
/* 6 */ "INVALID-%d\0"
|
||||
/* 17 */ "*INVALID*\0"
|
||||
/* 27 */ "none\0"
|
||||
/* 32 */ " + \0"
|
||||
/* 36 */ " | \0"
|
||||
/* 40 */ "%s\n\0"
|
||||
/* 44 */ "PAGER\0"
|
||||
/* 50 */ "/tmp/use.%lu\0"
|
||||
/* 63 */ "more\0"
|
||||
/* 68 */ " --* )\n\0"
|
||||
/* 79 */ "%s\n"
|
||||
" \0"
|
||||
/* 85 */ " \0"
|
||||
/* 88 */ " -* )\n\0"
|
||||
/* 98 */ " ;;\n\n\0"
|
||||
/* 111 */ "stdout\0"
|
||||
/* 118 */ "%A %B %e, %Y at %r %Z\0"
|
||||
/* 140 */ "#! %s\n\0"
|
||||
/* 147 */ "%s_%s=\0"
|
||||
/* 154 */ "\n"
|
||||
"export %s_%s\n\0"
|
||||
/* 169 */ "''\0"
|
||||
/* 172 */ "\\'\0"
|
||||
/* 175 */ "'%s'\0"
|
||||
/* 180 */ "%s_%s_%d=\0"
|
||||
/* 190 */ "\n"
|
||||
"export %s_%s_%d\n\0"
|
||||
/* 208 */ "set --\0"
|
||||
/* 215 */ " '%s'\0"
|
||||
/* 221 */ "'\\''\0"
|
||||
/* 226 */ "\n"
|
||||
"OPTION_CT=0\n\0"
|
||||
/* 240 */ "=%1$lu # 0x%1$lX\n\0"
|
||||
/* 258 */ "true\0"
|
||||
/* 263 */ "false\0"
|
||||
/* 269 */ "VERSION\0"
|
||||
/* 277 */ "OPT_ARG_NEEDED=OK\0"
|
||||
/* 295 */ "OPT_ARG_NEEDED=NO\0"
|
||||
/* 313 */ "OPT_ARG_NEEDED=YES\0"
|
||||
/* 332 */ "LONGUSAGE\0"
|
||||
/* 342 */ "flag\0"
|
||||
/* 347 */ "%s_%s_TEXT='\0"
|
||||
/* 360 */ "'\n\n\0"
|
||||
/* 364 */ "option\0"
|
||||
/* 371 */ "\n"
|
||||
"env | grep '^%s_'\n\0"
|
||||
/* 391 */ " -- %s\0"
|
||||
/* 398 */ "--\0"
|
||||
/* 401 */ "\t\t\t\t- \0"
|
||||
/* 408 */ "\t\t\t\t \0"
|
||||
/* 415 */ "\t\0"
|
||||
/* 417 */ " * )\n"
|
||||
" OPT_PROCESS=false\n"
|
||||
" ;;\n"
|
||||
" esac\n\0"
|
||||
/* 474 */ " %s\n\0"
|
||||
/* 480 */ "%%-%ds\0"
|
||||
/* 487 */ "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu\0"
|
||||
/* 530 */ "# # # # # # # # # # -- do not modify this marker --\n"
|
||||
"#\n"
|
||||
"# DO NOT EDIT THIS SECTION\n\0"
|
||||
/* 613 */ "%s OF %s\n"
|
||||
"#\n"
|
||||
"# From here to the next `-- do not modify this marker --',\n"
|
||||
"# the text has been generated %s\n\0"
|
||||
/* 719 */ "# From the %s option definitions\n"
|
||||
"#\n\0"
|
||||
/* 756 */ "\n"
|
||||
"if test -z \"${%1$s_%2$s}\"\n"
|
||||
"then\n"
|
||||
" %1$s_%2$s_CT=0\n"
|
||||
"else\n"
|
||||
" %1$s_%2$s_CT=1\n"
|
||||
" %1$s_%2$s_1=${%1$s_%2$s}\n"
|
||||
"fi\n"
|
||||
"export %1$s_%2$s_CT\0"
|
||||
/* 877 */ "\n"
|
||||
"%1$s_%2$s=${%1$s_%2$s-'%3$s'}\n"
|
||||
"%1$s_%2$s_set=false\n"
|
||||
"export %1$s_%2$s\0"
|
||||
/* 945 */ "\n"
|
||||
"%1$s_%2$s=${%1$s_%2$s}\n"
|
||||
"%1$s_%2$s_set=false\n"
|
||||
"export %1$s_%2$s\n\0"
|
||||
/* 1007 */ "\n"
|
||||
"OPT_PROCESS=true\n"
|
||||
"OPT_ARG=$1\n"
|
||||
"while ${OPT_PROCESS} && [ $# -gt 0 ]\n"
|
||||
"do\n"
|
||||
" OPT_ELEMENT=''\n"
|
||||
" OPT_ARG_VAL=''\n\n"
|
||||
" case \"${OPT_ARG}\" in\n"
|
||||
" -- )\n"
|
||||
" OPT_PROCESS=false\n"
|
||||
" shift\n"
|
||||
" ;;\n\0"
|
||||
/* 1201 */ "\n"
|
||||
"OPT_ARG=$1\n"
|
||||
"while [ $# -gt 0 ]\n"
|
||||
"do\n"
|
||||
" OPT_ELEMENT=''\n"
|
||||
" OPT_ARG_VAL=''\n"
|
||||
" OPT_ARG=${1}\n\0"
|
||||
/* 1291 */ " if [ -n \"${OPT_ARG_VAL}\" ]\n"
|
||||
" then\n"
|
||||
" eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n"
|
||||
" export %1$s_${OPT_NAME}${OPT_ELEMENT}\n"
|
||||
" fi\n"
|
||||
"done\n"
|
||||
"unset OPT_PROCESS || :\n"
|
||||
"unset OPT_ELEMENT || :\n"
|
||||
"unset OPT_ARG || :\n"
|
||||
"unset OPT_ARG_NEEDED || :\n"
|
||||
"unset OPT_NAME || :\n"
|
||||
"unset OPT_CODE || :\n"
|
||||
"unset OPT_ARG_VAL || :\n"
|
||||
"%2$s\0"
|
||||
/* 1621 */ "\n"
|
||||
"# # # # # # # # # #\n"
|
||||
"#\n"
|
||||
"# END OF AUTOMATED OPTION PROCESSING\n"
|
||||
"#\n"
|
||||
"# # # # # # # # # # -- do not modify this marker --\n\0"
|
||||
/* 1737 */ " case \"${OPT_CODE}\" in\n\0"
|
||||
/* 1768 */ " '%s' | \\\n\0"
|
||||
/* 1786 */ " '%s' )\n\0"
|
||||
/* 1802 */ " '%c' )\n\0"
|
||||
/* 1818 */ " ;;\n\n\0"
|
||||
/* 1835 */ " * )\n"
|
||||
" echo Unknown %s: \"${OPT_CODE}\" >&2\n"
|
||||
" echo \"$%s_USAGE_TEXT\"\n"
|
||||
" exit 1\n"
|
||||
" ;;\n"
|
||||
" esac\n\n\0"
|
||||
/* 1977 */ " echo \"$%s_%s_TEXT\"\n"
|
||||
" exit 0\n\0"
|
||||
/* 2028 */ " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
|
||||
" exit 0\n\0"
|
||||
/* 2102 */ " %s\n\0"
|
||||
/* 2118 */ " if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n"
|
||||
" echo Error: more than %3$d %2$s options >&2\n"
|
||||
" echo \"$%1$s_USAGE_TEXT\"\n"
|
||||
" exit 1 ; fi\n\0"
|
||||
/* 2297 */ " %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n"
|
||||
" OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n"
|
||||
" OPT_NAME='%2$s'\n\0"
|
||||
/* 2421 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
|
||||
" echo Error: duplicate %2$s option >&2\n"
|
||||
" echo \"$%1$s_USAGE_TEXT\"\n"
|
||||
" exit 1 ; fi\n"
|
||||
" %1$s_%2$s_set=true\n"
|
||||
" OPT_NAME='%2$s'\n\0"
|
||||
/* 2668 */ " %1$s_%2$s_CT=0\n"
|
||||
" OPT_ELEMENT=''\n"
|
||||
" %1$s_%2$s='%3$s'\n"
|
||||
" export %1$s_%2$s\n"
|
||||
" OPT_NAME='%2$s'\n\0"
|
||||
/* 2809 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
|
||||
" echo 'Error: duplicate %2$s option' >&2\n"
|
||||
" echo \"$%1$s_USAGE_TEXT\"\n"
|
||||
" exit 1 ; fi\n"
|
||||
" %1$s_%2$s_set=true\n"
|
||||
" %1$s_%2$s='%3$s'\n"
|
||||
" export %1$s_%2$s\n"
|
||||
" OPT_NAME='%2$s'\n\0"
|
||||
/* 3116 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n"
|
||||
" export %1$s_%2$s${OPT_ELEMENT}\n"
|
||||
" OPT_ARG_NEEDED=OK\n\0"
|
||||
/* 3236 */ " OPT_ARG_NEEDED=YES\n\0"
|
||||
/* 3268 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n"
|
||||
" export %1$s_%2$s${OPT_ELEMENT}\n"
|
||||
" OPT_ARG_NEEDED=NO\n\0"
|
||||
/* 3388 */ " OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n"
|
||||
" shift\n"
|
||||
" OPT_ARG=$1\n"
|
||||
" case \"${OPT_CODE}\" in *=* )\n"
|
||||
" OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n"
|
||||
" OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\0"
|
||||
/* 3639 */ " case \"${OPT_ARG_NEEDED}\" in\n"
|
||||
" NO )\n"
|
||||
" OPT_ARG_VAL=''\n"
|
||||
" ;;\n"
|
||||
" YES )\n"
|
||||
" if [ -z \"${OPT_ARG_VAL}\" ]\n"
|
||||
" then\n"
|
||||
" if [ $# -eq 0 ]\n"
|
||||
" then\n"
|
||||
" echo No argument provided for ${OPT_NAME} option >&2\n"
|
||||
" echo \"$%s_USAGE_TEXT\"\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" OPT_ARG_VAL=${OPT_ARG}\n"
|
||||
" shift\n"
|
||||
" OPT_ARG=$1\n"
|
||||
" fi\n"
|
||||
" ;;\n"
|
||||
" OK )\n"
|
||||
" if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n"
|
||||
" then\n"
|
||||
" case \"${OPT_ARG}\" in -* ) ;; * )\n"
|
||||
" OPT_ARG_VAL=${OPT_ARG}\n"
|
||||
" shift\n"
|
||||
" OPT_ARG=$1 ;; esac\n"
|
||||
" fi\n"
|
||||
" ;;\n"
|
||||
" esac\n\0"
|
||||
/* 4418 */ " OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n"
|
||||
" OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\0"
|
||||
/* 4535 */ " case \"${OPT_ARG_NEEDED}\" in\n"
|
||||
" NO )\n"
|
||||
" if [ -n \"${OPT_ARG}\" ]\n"
|
||||
" then\n"
|
||||
" OPT_ARG=-${OPT_ARG}\n"
|
||||
" else\n"
|
||||
" shift\n"
|
||||
" OPT_ARG=$1\n"
|
||||
" fi\n"
|
||||
" ;;\n"
|
||||
" YES )\n"
|
||||
" if [ -n \"${OPT_ARG}\" ]\n"
|
||||
" then\n"
|
||||
" OPT_ARG_VAL=${OPT_ARG}\n"
|
||||
" else\n"
|
||||
" if [ $# -eq 0 ]\n"
|
||||
" then\n"
|
||||
" echo No argument provided for ${OPT_NAME} option >&2\n"
|
||||
" echo \"$%s_USAGE_TEXT\"\n"
|
||||
" exit 1\n"
|
||||
" fi\n"
|
||||
" shift\n"
|
||||
" OPT_ARG_VAL=$1\n"
|
||||
" fi\n"
|
||||
" shift\n"
|
||||
" OPT_ARG=$1\n"
|
||||
" ;;\n"
|
||||
" OK )\n"
|
||||
" if [ -n \"${OPT_ARG}\" ]\n"
|
||||
" then\n"
|
||||
" OPT_ARG_VAL=${OPT_ARG}\n"
|
||||
" shift\n"
|
||||
" OPT_ARG=$1\n"
|
||||
" else\n"
|
||||
" shift\n"
|
||||
" if [ $# -gt 0 ]\n"
|
||||
" then\n"
|
||||
" case \"$1\" in -* ) ;; * )\n"
|
||||
" OPT_ARG_VAL=$1\n"
|
||||
" shift ;; esac\n"
|
||||
" OPT_ARG=$1\n"
|
||||
" fi\n"
|
||||
" fi\n"
|
||||
" ;;\n"
|
||||
" esac\n\0"
|
||||
/* 5689 */ "%1$s_%2$s=%3$d # 0x%3$X\n"
|
||||
"export %1$s_%2$s\n\0"
|
||||
/* 5731 */ "%1$s_%2$s_CT=%3$d\n"
|
||||
"export %1$s_%2$s_CT\n\0"
|
||||
/* 5770 */ "OPTION_CT=%d\n"
|
||||
"export OPTION_CT\n\0"
|
||||
/* 5801 */ "%1$s_%2$s=%3$s\n"
|
||||
"export %1$s_%2$s\n\0"
|
||||
/* 5834 */ "%1$s_%2$s='%3$s'\n"
|
||||
"export %1$s_%2$s\n\0"
|
||||
/* 5869 */ "%1$s_%2$s_MODE='%3$s'\n"
|
||||
"export %1$s_%2$s_MODE\n\0"
|
||||
/* 5914 */ "echo 'Warning: Cannot load options files' >&2\0"
|
||||
/* 5961 */ "echo 'Warning: Cannot save options files' >&2\0"
|
||||
/* 6008 */ "echo 'Warning: Cannot suppress the loading of options files' >&2\0"
|
||||
/* 6074 */ "%1$s_%2$s_TEXT='no %2$s text'\n\0"
|
||||
/* 6105 */ "%s WARNING: cannot save options - \0"
|
||||
/* 6141 */ "<%s/>\n\0"
|
||||
/* 6148 */ "<%s>\0"
|
||||
/* 6153 */ "</%s>\n\0"
|
||||
/* 6160 */ "<%s type=%s>\0"
|
||||
/* 6173 */ "<%s type=nested>\n\0"
|
||||
/* 6191 */ "#x%02X;\0"
|
||||
/* 6199 */ "<%1$s type=boolean>%2$s</%1$s>\n\0"
|
||||
/* 6231 */ "<%1$s type=integer>0x%2$lX</%1$s>\n";
|
||||
|
||||
/* end of ao-strs.c */
|
||||
@@ -0,0 +1,251 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ao-strs.h)
|
||||
*
|
||||
* It has been AutoGen-ed May 6, 2012 at 04:20:58 PM by AutoGen 5.16pre36
|
||||
* From the definitions ao-strs.def
|
||||
* and the template file strings
|
||||
*
|
||||
* Copyright (C) 2011-2012 Bruce Korb, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* Modified (3 clause) Berkeley Software Distribution License
|
||||
* <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name ``Bruce Korb'' nor the name of any other
|
||||
* contributor may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef STRINGS_AO_STRS_H_GUARD
|
||||
#define STRINGS_AO_STRS_H_GUARD 1
|
||||
/*
|
||||
* 102 strings in ao_strs_strtable string table
|
||||
*/
|
||||
#define ARG_BREAK_STR (ao_strs_strtable+0)
|
||||
#define ARG_BREAK_STR_LEN 5
|
||||
#define INVALID_FMT (ao_strs_strtable+6)
|
||||
#define INVALID_FMT_LEN 10
|
||||
#define INVALID_STR (ao_strs_strtable+17)
|
||||
#define INVALID_STR_LEN 9
|
||||
#define NONE_STR (ao_strs_strtable+27)
|
||||
#define NONE_STR_LEN 4
|
||||
#define PLUS_STR (ao_strs_strtable+32)
|
||||
#define PLUS_STR_LEN 3
|
||||
#define OR_STR (ao_strs_strtable+36)
|
||||
#define OR_STR_LEN 3
|
||||
#define NLSTR_FMT (ao_strs_strtable+40)
|
||||
#define NLSTR_FMT_LEN 3
|
||||
#define PAGER_NAME (ao_strs_strtable+44)
|
||||
#define PAGER_NAME_LEN 5
|
||||
#define TMP_USAGE_FMT (ao_strs_strtable+50)
|
||||
#define TMP_USAGE_FMT_LEN 12
|
||||
#define MORE_STR (ao_strs_strtable+63)
|
||||
#define MORE_STR_LEN 4
|
||||
#define LONG_OPT_MARK (ao_strs_strtable+68)
|
||||
#define LONG_OPT_MARK_LEN 10
|
||||
#define NLSTR_SPACE_FMT (ao_strs_strtable+79)
|
||||
#define NLSTR_SPACE_FMT_LEN 5
|
||||
#define TWO_SPACES_STR (ao_strs_strtable+85)
|
||||
#define TWO_SPACES_STR_LEN 2
|
||||
#define FLAG_OPT_MARK (ao_strs_strtable+88)
|
||||
#define FLAG_OPT_MARK_LEN 9
|
||||
#define END_OPT_SEL_STR (ao_strs_strtable+98)
|
||||
#define END_OPT_SEL_STR_LEN 12
|
||||
#define STDOUT (ao_strs_strtable+111)
|
||||
#define STDOUT_LEN 6
|
||||
#define TIME_FMT (ao_strs_strtable+118)
|
||||
#define TIME_FMT_LEN 21
|
||||
#define SHELL_MAGIC (ao_strs_strtable+140)
|
||||
#define SHELL_MAGIC_LEN 6
|
||||
#define OPT_VAL_FMT (ao_strs_strtable+147)
|
||||
#define OPT_VAL_FMT_LEN 6
|
||||
#define OPT_END_FMT (ao_strs_strtable+154)
|
||||
#define OPT_END_FMT_LEN 14
|
||||
#define EMPTY_ARG (ao_strs_strtable+169)
|
||||
#define EMPTY_ARG_LEN 2
|
||||
#define QUOT_APOS (ao_strs_strtable+172)
|
||||
#define QUOT_APOS_LEN 2
|
||||
#define QUOT_ARG_FMT (ao_strs_strtable+175)
|
||||
#define QUOT_ARG_FMT_LEN 4
|
||||
#define ARG_BY_NUM_FMT (ao_strs_strtable+180)
|
||||
#define ARG_BY_NUM_FMT_LEN 9
|
||||
#define EXPORT_ARG_FMT (ao_strs_strtable+190)
|
||||
#define EXPORT_ARG_FMT_LEN 17
|
||||
#define set_dash (ao_strs_strtable+208)
|
||||
#define set_dash_LEN 6
|
||||
#define arg_fmt (ao_strs_strtable+215)
|
||||
#define arg_fmt_LEN 5
|
||||
#define apostrophy (ao_strs_strtable+221)
|
||||
#define apostrophy_LEN 4
|
||||
#define init_optct (ao_strs_strtable+226)
|
||||
#define init_optct_LEN 13
|
||||
#define SHOW_VAL_FMT (ao_strs_strtable+240)
|
||||
#define SHOW_VAL_FMT_LEN 17
|
||||
#define TRUE_STR (ao_strs_strtable+258)
|
||||
#define TRUE_STR_LEN 4
|
||||
#define FALSE_STR (ao_strs_strtable+263)
|
||||
#define FALSE_STR_LEN 5
|
||||
#define VER_STR (ao_strs_strtable+269)
|
||||
#define VER_STR_LEN 7
|
||||
#define OK_NEED_OPT_ARG (ao_strs_strtable+277)
|
||||
#define OK_NEED_OPT_ARG_LEN 17
|
||||
#define NO_ARG_NEEDED (ao_strs_strtable+295)
|
||||
#define NO_ARG_NEEDED_LEN 17
|
||||
#define YES_NEED_OPT_ARG (ao_strs_strtable+313)
|
||||
#define YES_NEED_OPT_ARG_LEN 18
|
||||
#define LONG_USE_STR (ao_strs_strtable+332)
|
||||
#define LONG_USE_STR_LEN 9
|
||||
#define FLAG_STR (ao_strs_strtable+342)
|
||||
#define FLAG_STR_LEN 4
|
||||
#define SET_TEXT_FMT (ao_strs_strtable+347)
|
||||
#define SET_TEXT_FMT_LEN 12
|
||||
#define END_SET_TEXT (ao_strs_strtable+360)
|
||||
#define END_SET_TEXT_LEN 3
|
||||
#define OPTION_STR (ao_strs_strtable+364)
|
||||
#define OPTION_STR_LEN 6
|
||||
#define SHOW_PROG_ENV (ao_strs_strtable+371)
|
||||
#define SHOW_PROG_ENV_LEN 19
|
||||
#define SET_OFF_FMT (ao_strs_strtable+391)
|
||||
#define SET_OFF_FMT_LEN 6
|
||||
#define LONG_OPT_MARKER (ao_strs_strtable+398)
|
||||
#define LONG_OPT_MARKER_LEN 2
|
||||
#define BULLET_STR (ao_strs_strtable+401)
|
||||
#define BULLET_STR_LEN 6
|
||||
#define DEEP_INDENT_STR (ao_strs_strtable+408)
|
||||
#define DEEP_INDENT_STR_LEN 6
|
||||
#define ONE_TAB_STR (ao_strs_strtable+415)
|
||||
#define ONE_TAB_STR_LEN 1
|
||||
#define NOT_FOUND_STR (ao_strs_strtable+417)
|
||||
#define NOT_FOUND_STR_LEN 56
|
||||
#define ENUM_ERR_SEP_LINE_FMT (ao_strs_strtable+474)
|
||||
#define ENUM_ERR_SEP_LINE_FMT_LEN 5
|
||||
#define ENUM_ERR_STR_WIDTH_FMT (ao_strs_strtable+480)
|
||||
#define ENUM_ERR_STR_WIDTH_FMT_LEN 6
|
||||
#define PAGE_USAGE_FMT (ao_strs_strtable+487)
|
||||
#define PAGE_USAGE_FMT_LEN 42
|
||||
#define START_MARK (ao_strs_strtable+530)
|
||||
#define START_MARK_LEN 82
|
||||
#define PREAMBLE_FMT (ao_strs_strtable+613)
|
||||
#define PREAMBLE_FMT_LEN 105
|
||||
#define END_PRE_FMT (ao_strs_strtable+719)
|
||||
#define END_PRE_FMT_LEN 36
|
||||
#define MULTI_DEF_FMT (ao_strs_strtable+756)
|
||||
#define MULTI_DEF_FMT_LEN 120
|
||||
#define SGL_DEF_FMT (ao_strs_strtable+877)
|
||||
#define SGL_DEF_FMT_LEN 67
|
||||
#define SGL_NO_DEF_FMT (ao_strs_strtable+945)
|
||||
#define SGL_NO_DEF_FMT_LEN 61
|
||||
#define LOOP_STR (ao_strs_strtable+1007)
|
||||
#define LOOP_STR_LEN 193
|
||||
#define ONLY_OPTS_LOOP (ao_strs_strtable+1201)
|
||||
#define ONLY_OPTS_LOOP_LEN 89
|
||||
#define zLoopEnd (ao_strs_strtable+1291)
|
||||
#define zLoopEnd_LEN 329
|
||||
#define END_MARK (ao_strs_strtable+1621)
|
||||
#define END_MARK_LEN 115
|
||||
#define zOptionCase (ao_strs_strtable+1737)
|
||||
#define zOptionCase_LEN 30
|
||||
#define zOptionPartName (ao_strs_strtable+1768)
|
||||
#define zOptionPartName_LEN 17
|
||||
#define zOptionFullName (ao_strs_strtable+1786)
|
||||
#define zOptionFullName_LEN 15
|
||||
#define zOptionFlag (ao_strs_strtable+1802)
|
||||
#define zOptionFlag_LEN 15
|
||||
#define zOptionEndSelect (ao_strs_strtable+1818)
|
||||
#define zOptionEndSelect_LEN 16
|
||||
#define UNK_OPT_FMT (ao_strs_strtable+1835)
|
||||
#define UNK_OPT_FMT_LEN 141
|
||||
#define zTextExit (ao_strs_strtable+1977)
|
||||
#define zTextExit_LEN 50
|
||||
#define zPagedUsageExit (ao_strs_strtable+2028)
|
||||
#define zPagedUsageExit_LEN 73
|
||||
#define zCmdFmt (ao_strs_strtable+2102)
|
||||
#define zCmdFmt_LEN 15
|
||||
#define zCountTest (ao_strs_strtable+2118)
|
||||
#define zCountTest_LEN 178
|
||||
#define MULTI_ARG_FMT (ao_strs_strtable+2297)
|
||||
#define MULTI_ARG_FMT_LEN 123
|
||||
#define SGL_ARG_FMT (ao_strs_strtable+2421)
|
||||
#define SGL_ARG_FMT_LEN 246
|
||||
#define NO_MULTI_ARG_FMT (ao_strs_strtable+2668)
|
||||
#define NO_MULTI_ARG_FMT_LEN 140
|
||||
#define NO_SGL_ARG_FMT (ao_strs_strtable+2809)
|
||||
#define NO_SGL_ARG_FMT_LEN 306
|
||||
#define zMayArg (ao_strs_strtable+3116)
|
||||
#define zMayArg_LEN 119
|
||||
#define zMustArg (ao_strs_strtable+3236)
|
||||
#define zMustArg_LEN 31
|
||||
#define zCantArg (ao_strs_strtable+3268)
|
||||
#define zCantArg_LEN 119
|
||||
#define INIT_LOPT_STR (ao_strs_strtable+3388)
|
||||
#define INIT_LOPT_STR_LEN 250
|
||||
#define LOPT_ARG_FMT (ao_strs_strtable+3639)
|
||||
#define LOPT_ARG_FMT_LEN 778
|
||||
#define INIT_OPT_STR (ao_strs_strtable+4418)
|
||||
#define INIT_OPT_STR_LEN 116
|
||||
#define OPT_ARG_FMT (ao_strs_strtable+4535)
|
||||
#define OPT_ARG_FMT_LEN 1153
|
||||
#define zOptNumFmt (ao_strs_strtable+5689)
|
||||
#define zOptNumFmt_LEN 41
|
||||
#define zOptCookieCt (ao_strs_strtable+5731)
|
||||
#define zOptCookieCt_LEN 38
|
||||
#define zOptCtFmt (ao_strs_strtable+5770)
|
||||
#define zOptCtFmt_LEN 30
|
||||
#define zOptDisabl (ao_strs_strtable+5801)
|
||||
#define zOptDisabl_LEN 32
|
||||
#define zFullOptFmt (ao_strs_strtable+5834)
|
||||
#define zFullOptFmt_LEN 34
|
||||
#define zEquivMode (ao_strs_strtable+5869)
|
||||
#define zEquivMode_LEN 44
|
||||
#define NO_LOAD_WARN (ao_strs_strtable+5914)
|
||||
#define NO_LOAD_WARN_LEN 46
|
||||
#define NO_SAVE_OPTS (ao_strs_strtable+5961)
|
||||
#define NO_SAVE_OPTS_LEN 46
|
||||
#define NO_SUPPRESS_LOAD (ao_strs_strtable+6008)
|
||||
#define NO_SUPPRESS_LOAD_LEN 65
|
||||
#define SET_NO_TEXT_FMT (ao_strs_strtable+6074)
|
||||
#define SET_NO_TEXT_FMT_LEN 30
|
||||
#define SAVE_WARN (ao_strs_strtable+6105)
|
||||
#define SAVE_WARN_LEN 35
|
||||
#define OPEN_CLOSE_FMT (ao_strs_strtable+6141)
|
||||
#define OPEN_CLOSE_FMT_LEN 6
|
||||
#define OPEN_XML_FMT (ao_strs_strtable+6148)
|
||||
#define OPEN_XML_FMT_LEN 4
|
||||
#define END_XML_FMT (ao_strs_strtable+6153)
|
||||
#define END_XML_FMT_LEN 6
|
||||
#define TYPE_ATR_FMT (ao_strs_strtable+6160)
|
||||
#define TYPE_ATR_FMT_LEN 12
|
||||
#define NULL_ATR_FMT (ao_strs_strtable+6141)
|
||||
#define NULL_ATR_FMT_LEN 6
|
||||
#define NESTED_OPT_FMT (ao_strs_strtable+6173)
|
||||
#define NESTED_OPT_FMT_LEN 17
|
||||
#define XML_HEX_BYTE_FMT (ao_strs_strtable+6191)
|
||||
#define XML_HEX_BYTE_FMT_LEN 7
|
||||
#define BOOL_ATR_FMT (ao_strs_strtable+6199)
|
||||
#define BOOL_ATR_FMT_LEN 31
|
||||
#define NUMB_ATR_FMT (ao_strs_strtable+6231)
|
||||
#define NUMB_ATR_FMT_LEN 34
|
||||
|
||||
extern char const ao_strs_strtable[6266];
|
||||
|
||||
#endif /* STRINGS_AO_STRS_H_GUARD */
|
||||
@@ -0,0 +1,729 @@
|
||||
|
||||
/**
|
||||
* \file autoopts.c
|
||||
*
|
||||
* Time-stamp: "2012-03-04 19:44:56 bkorb"
|
||||
*
|
||||
* This file contains all of the routines that must be linked into
|
||||
* an executable to use the generated option processing. The optional
|
||||
* routines are in separately compiled modules so that they will not
|
||||
* necessarily be linked in.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
#ifndef PKGDATADIR
|
||||
# define PKGDATADIR ""
|
||||
#endif
|
||||
|
||||
static char const zNil[] = "";
|
||||
static arg_types_t argTypes = { NULL };
|
||||
static char line_fmt_buf[32];
|
||||
static bool displayEnum = false;
|
||||
static char const pkgdatadir_default[] = PKGDATADIR;
|
||||
static char const * program_pkgdatadir = pkgdatadir_default;
|
||||
static tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED;
|
||||
static tePagerState pagerState = PAGER_STATE_INITIAL;
|
||||
|
||||
FILE * option_usage_fp = NULL;
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static tSuccess
|
||||
next_opt_arg_must(tOptions * pOpts, tOptState* pOptState);
|
||||
|
||||
static tSuccess
|
||||
next_opt_arg_may(tOptions * pOpts, tOptState * pOptState);
|
||||
|
||||
static tSuccess
|
||||
next_opt_arg_none(tOptions * pOpts, tOptState* pOptState);
|
||||
|
||||
static tSuccess
|
||||
next_opt(tOptions * pOpts, tOptState * pOptState);
|
||||
|
||||
static tSuccess
|
||||
doPresets(tOptions * pOpts);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
LOCAL void *
|
||||
ao_malloc(size_t sz)
|
||||
{
|
||||
void * res = malloc(sz);
|
||||
if (res == NULL) {
|
||||
fprintf(stderr, zAO_Alloc, (int)sz);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#undef malloc
|
||||
#define malloc(_s) ao_malloc(_s)
|
||||
|
||||
LOCAL void *
|
||||
ao_realloc(void *p, size_t sz)
|
||||
{
|
||||
void * res = (p == NULL) ? malloc(sz) : realloc(p, sz);
|
||||
if (res == NULL) {
|
||||
fprintf(stderr, zAO_Realloc, (int)sz, p);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#undef realloc
|
||||
#define realloc(_p,_s) ao_realloc(_p,_s)
|
||||
|
||||
LOCAL char *
|
||||
ao_strdup(char const *str)
|
||||
{
|
||||
char * res = strdup(str);
|
||||
if (res == NULL) {
|
||||
fprintf(stderr, zAO_Strdup, (int)strlen(str));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#undef strdup
|
||||
#define strdup(_p) ao_strdup(_p)
|
||||
|
||||
#ifndef HAVE_PATHFIND
|
||||
# include "compat/pathfind.c"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# include "compat/snprintf.c"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
# include "compat/strdup.c"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCHR
|
||||
# include "compat/strchr.c"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* handle_opt
|
||||
*
|
||||
* This routine handles equivalencing, sets the option state flags and
|
||||
* invokes the handler procedure, if any.
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
handle_opt(tOptions * pOpts, tOptState* pOptState)
|
||||
{
|
||||
/*
|
||||
* Save a copy of the option procedure pointer.
|
||||
* If this is an equivalence class option, we still want this proc.
|
||||
*/
|
||||
tOptDesc* pOD = pOptState->pOD;
|
||||
tOptProc* pOP = pOD->pOptProc;
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG)
|
||||
AGFREE(pOD->optArg.argString);
|
||||
|
||||
pOD->optArg.argString = pOptState->pzOptArg;
|
||||
|
||||
/*
|
||||
* IF we are presetting options, then we will ignore any un-presettable
|
||||
* options. They are the ones either marked as such.
|
||||
*/
|
||||
if ( ((pOpts->fOptSet & OPTPROC_PRESETTING) != 0)
|
||||
&& ((pOD->fOptState & OPTST_NO_INIT) != 0)
|
||||
)
|
||||
return PROBLEM;
|
||||
|
||||
/*
|
||||
* IF this is an equivalence class option,
|
||||
* THEN
|
||||
* Save the option value that got us to this option
|
||||
* entry. (It may not be pOD->optChar[0], if this is an
|
||||
* equivalence entry.)
|
||||
* set the pointer to the equivalence class base
|
||||
*/
|
||||
if (pOD->optEquivIndex != NO_EQUIVALENT) {
|
||||
tOptDesc* p = pOpts->pOptDesc + pOD->optEquivIndex;
|
||||
|
||||
/*
|
||||
* IF the current option state has not been defined (set on the
|
||||
* command line), THEN we will allow continued resetting of
|
||||
* the value. Once "defined", then it must not change.
|
||||
*/
|
||||
if ((pOD->fOptState & OPTST_DEFINED) != 0) {
|
||||
/*
|
||||
* The equivalenced-to option has been found on the command
|
||||
* line before. Make sure new occurrences are the same type.
|
||||
*
|
||||
* IF this option has been previously equivalenced and
|
||||
* it was not the same equivalenced-to option,
|
||||
* THEN we have a usage problem.
|
||||
*/
|
||||
if (p->optActualIndex != pOD->optIndex) {
|
||||
fprintf(stderr, (char*)zMultiEquiv, p->pz_Name, pOD->pz_Name,
|
||||
(pOpts->pOptDesc + p->optActualIndex)->pz_Name);
|
||||
return FAILURE;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Set the equivalenced-to actual option index to no-equivalent
|
||||
* so that we set all the entries below. This option may either
|
||||
* never have been selected before, or else it was selected by
|
||||
* some sort of "presetting" mechanism.
|
||||
*/
|
||||
p->optActualIndex = NO_EQUIVALENT;
|
||||
}
|
||||
|
||||
if (p->optActualIndex != pOD->optIndex) {
|
||||
/*
|
||||
* First time through, copy over the state
|
||||
* and add in the equivalence flag
|
||||
*/
|
||||
p->optActualValue = pOD->optValue;
|
||||
p->optActualIndex = pOD->optIndex;
|
||||
pOptState->flags |= OPTST_EQUIVALENCE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the most recent option argument. set membership state
|
||||
* is kept in ``p->optCookie''. Do not overwrite.
|
||||
*/
|
||||
p->optArg.argString = pOD->optArg.argString;
|
||||
pOD = p;
|
||||
|
||||
} else {
|
||||
pOD->optActualValue = pOD->optValue;
|
||||
pOD->optActualIndex = pOD->optIndex;
|
||||
}
|
||||
|
||||
pOD->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
pOD->fOptState |= (pOptState->flags & ~OPTST_PERSISTENT_MASK);
|
||||
|
||||
/*
|
||||
* Keep track of count only for DEFINED (command line) options.
|
||||
* IF we have too many, build up an error message and bail.
|
||||
*/
|
||||
if ( (pOD->fOptState & OPTST_DEFINED)
|
||||
&& (++pOD->optOccCt > pOD->optMaxCt) ) {
|
||||
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
char const * pzEqv =
|
||||
(pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil;
|
||||
|
||||
fputs(zErrOnly, stderr);
|
||||
|
||||
if (pOD->optMaxCt > 1)
|
||||
fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv);
|
||||
else
|
||||
fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv);
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If provided a procedure to call, call it
|
||||
*/
|
||||
if (pOP != NULL)
|
||||
(*pOP)(pOpts, pOD);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static tSuccess
|
||||
next_opt_arg_must(tOptions * pOpts, tOptState* pOptState)
|
||||
{
|
||||
/*
|
||||
* An option argument is required. Long options can either have
|
||||
* a separate command line argument, or an argument attached by
|
||||
* the '=' character. Figure out which.
|
||||
*/
|
||||
switch (pOptState->optType) {
|
||||
case TOPT_SHORT:
|
||||
/*
|
||||
* See if an arg string follows the flag character
|
||||
*/
|
||||
if (*++(pOpts->pzCurOpt) == NUL)
|
||||
pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx++ ];
|
||||
pOptState->pzOptArg = pOpts->pzCurOpt;
|
||||
break;
|
||||
|
||||
case TOPT_LONG:
|
||||
/*
|
||||
* See if an arg string has already been assigned (glued on
|
||||
* with an `=' character)
|
||||
*/
|
||||
if (pOptState->pzOptArg == NULL)
|
||||
pOptState->pzOptArg = pOpts->origArgVect[ pOpts->curOptIdx++ ];
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef DEBUG
|
||||
fputs("AutoOpts lib error: option type not selected\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
|
||||
case TOPT_DEFAULT:
|
||||
/*
|
||||
* The option was selected by default. The current token is
|
||||
* the option argument.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure we did not overflow the argument list.
|
||||
*/
|
||||
if (pOpts->curOptIdx > pOpts->origArgCt) {
|
||||
fprintf(stderr, zMisArg, pOpts->pzProgPath, pOptState->pOD->pz_Name);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
pOpts->pzCurOpt = NULL; /* next time advance to next arg */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an optional option argument. For short options, it looks at the
|
||||
* character after the option character, or it consumes the next full argument.
|
||||
* For long options, it looks for an '=' character attachment to the long
|
||||
* option name before deciding to take the next command line argument.
|
||||
*
|
||||
* @param pOpts the option descriptor
|
||||
* @param pOptState a structure for managing the current processing state
|
||||
* @returns SUCCESS or does not return
|
||||
*/
|
||||
static tSuccess
|
||||
next_opt_arg_may(tOptions * pOpts, tOptState * pOptState)
|
||||
{
|
||||
/*
|
||||
* An option argument is optional.
|
||||
*/
|
||||
switch (pOptState->optType) {
|
||||
case TOPT_SHORT:
|
||||
if (*++pOpts->pzCurOpt != NUL)
|
||||
pOptState->pzOptArg = pOpts->pzCurOpt;
|
||||
else {
|
||||
char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
|
||||
|
||||
/*
|
||||
* BECAUSE it is optional, we must make sure
|
||||
* we did not find another flag and that there
|
||||
* is such an argument.
|
||||
*/
|
||||
if ((pzLA == NULL) || (*pzLA == '-'))
|
||||
pOptState->pzOptArg = NULL;
|
||||
else {
|
||||
pOpts->curOptIdx++; /* argument found */
|
||||
pOptState->pzOptArg = pzLA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TOPT_LONG:
|
||||
/*
|
||||
* Look for an argument if we don't already have one (glued on
|
||||
* with a `=' character) *AND* we are not in named argument mode
|
||||
*/
|
||||
if ( (pOptState->pzOptArg == NULL)
|
||||
&& (! NAMED_OPTS(pOpts))) {
|
||||
char* pzLA = pOpts->origArgVect[ pOpts->curOptIdx ];
|
||||
|
||||
/*
|
||||
* BECAUSE it is optional, we must make sure
|
||||
* we did not find another flag and that there
|
||||
* is such an argument.
|
||||
*/
|
||||
if ((pzLA == NULL) || (*pzLA == '-'))
|
||||
pOptState->pzOptArg = NULL;
|
||||
else {
|
||||
pOpts->curOptIdx++; /* argument found */
|
||||
pOptState->pzOptArg = pzLA;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
case TOPT_DEFAULT:
|
||||
fputs(zAO_Woops, stderr );
|
||||
exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
/*
|
||||
* After an option with an optional argument, we will
|
||||
* *always* start with the next option because if there
|
||||
* were any characters following the option name/flag,
|
||||
* they would be interpreted as the argument.
|
||||
*/
|
||||
pOpts->pzCurOpt = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static tSuccess
|
||||
next_opt_arg_none(tOptions * pOpts, tOptState* pOptState)
|
||||
{
|
||||
/*
|
||||
* No option argument. Make sure next time around we find
|
||||
* the correct option flag character for short options
|
||||
*/
|
||||
if (pOptState->optType == TOPT_SHORT)
|
||||
(pOpts->pzCurOpt)++;
|
||||
|
||||
/*
|
||||
* It is a long option. Make sure there was no ``=xxx'' argument
|
||||
*/
|
||||
else if (pOptState->pzOptArg != NULL) {
|
||||
fprintf(stderr, zNoArg, pOpts->pzProgPath, pOptState->pOD->pz_Name);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* It is a long option. Advance to next command line argument.
|
||||
*/
|
||||
else
|
||||
pOpts->pzCurOpt = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the option descriptor and option argument (if any) for the
|
||||
* next command line argument. DO NOT modify the descriptor. Put
|
||||
* all the state in the state argument so that the option can be skipped
|
||||
* without consequence (side effect).
|
||||
*
|
||||
* @param pOpts the program option descriptor
|
||||
* @param pOptState the state of the next found option
|
||||
*/
|
||||
static tSuccess
|
||||
next_opt(tOptions * pOpts, tOptState * pOptState)
|
||||
{
|
||||
{
|
||||
tSuccess res = find_opt(pOpts, pOptState);
|
||||
if (! SUCCESSFUL(res))
|
||||
return res;
|
||||
}
|
||||
|
||||
if ( ((pOptState->flags & OPTST_DEFINED) != 0)
|
||||
&& ((pOptState->pOD->fOptState & OPTST_NO_COMMAND) != 0)) {
|
||||
fprintf(stderr, zNotCmdOpt, pOptState->pOD->pz_Name);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return get_opt_arg(pOpts, pOptState);
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* DO PRESETS
|
||||
*
|
||||
* The next several routines do the immediate action pass on the command
|
||||
* line options, then the environment variables, then the config files in
|
||||
* reverse order. Once done with that, the order is reversed and all
|
||||
* the config files and environment variables are processed again, this
|
||||
* time only processing the non-immediate action options. doPresets()
|
||||
* will then return for optionProcess() to do the final pass on the command
|
||||
* line arguments.
|
||||
*/
|
||||
|
||||
/**
|
||||
* scan the command line for immediate action options.
|
||||
* This is only called the first time through.
|
||||
* While this procedure is active, the OPTPROC_IMMEDIATE is true.
|
||||
*
|
||||
* @param pOpts program options descriptor
|
||||
* @returns SUCCESS or FAILURE
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
immediate_opts(tOptions * pOpts)
|
||||
{
|
||||
tSuccess res;
|
||||
|
||||
pOpts->fOptSet |= OPTPROC_IMMEDIATE;
|
||||
pOpts->curOptIdx = 1; /* start by skipping program name */
|
||||
pOpts->pzCurOpt = NULL;
|
||||
|
||||
/*
|
||||
* Examine all the options from the start. We process any options that
|
||||
* are marked for immediate processing.
|
||||
*/
|
||||
for (;;) {
|
||||
tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
|
||||
|
||||
res = next_opt(pOpts, &opt_st);
|
||||
switch (res) {
|
||||
case FAILURE: goto failed_option;
|
||||
case PROBLEM: res = SUCCESS; goto leave;
|
||||
case SUCCESS: break;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF this is an immediate-attribute option, then do it.
|
||||
*/
|
||||
if (! DO_IMMEDIATELY(opt_st.flags))
|
||||
continue;
|
||||
|
||||
if (! SUCCESSFUL(handle_opt(pOpts, &opt_st)))
|
||||
break;
|
||||
} failed_option:;
|
||||
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
|
||||
(*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
|
||||
|
||||
leave:
|
||||
|
||||
pOpts->fOptSet &= ~OPTPROC_IMMEDIATE;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all the options from our current position onward. (This allows
|
||||
* interspersed options and arguments for the few non-standard programs that
|
||||
* require it.) Thus, do not rewind option indexes because some programs
|
||||
* choose to re-invoke after a non-option.
|
||||
*
|
||||
* @param pOpts program options descriptor
|
||||
* @returns SUCCESS or FAILURE
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
regular_opts(tOptions * pOpts)
|
||||
{
|
||||
/* assert: pOpts->fOptSet & OPTPROC_IMMEDIATE == 0 */
|
||||
for (;;) {
|
||||
tOptState opt_st = OPTSTATE_INITIALIZER(DEFINED);
|
||||
|
||||
switch (next_opt(pOpts, &opt_st)) {
|
||||
case FAILURE: goto failed_option;
|
||||
case PROBLEM: return SUCCESS; /* no more args */
|
||||
case SUCCESS: break;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF this is an immediate action option,
|
||||
* THEN skip it (unless we are supposed to do it a second time).
|
||||
*/
|
||||
if (! DO_NORMALLY(opt_st.flags)) {
|
||||
if (! DO_SECOND_TIME(opt_st.flags))
|
||||
continue;
|
||||
opt_st.pOD->optOccCt--; /* don't count this repetition */
|
||||
}
|
||||
|
||||
if (! SUCCESSFUL(handle_opt(pOpts, &opt_st)))
|
||||
break;
|
||||
} failed_option:;
|
||||
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
|
||||
(*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check for preset values from a config files or envrionment variables
|
||||
*/
|
||||
static tSuccess
|
||||
doPresets(tOptions * pOpts)
|
||||
{
|
||||
tOptDesc * pOD = NULL;
|
||||
|
||||
if (! SUCCESSFUL(immediate_opts(pOpts)))
|
||||
return FAILURE;
|
||||
|
||||
/*
|
||||
* IF this option set has a --save-opts option, then it also
|
||||
* has a --load-opts option. See if a command line option has disabled
|
||||
* option presetting.
|
||||
*/
|
||||
if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
|
||||
&& (pOpts->specOptIdx.save_opts != 0)) {
|
||||
pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
|
||||
if (DISABLED_OPT(pOD))
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Until we return from this procedure, disable non-presettable opts
|
||||
*/
|
||||
pOpts->fOptSet |= OPTPROC_PRESETTING;
|
||||
/*
|
||||
* IF there are no config files,
|
||||
* THEN do any environment presets and leave.
|
||||
*/
|
||||
if (pOpts->papzHomeList == NULL) {
|
||||
env_presets(pOpts, ENV_ALL);
|
||||
}
|
||||
else {
|
||||
env_presets(pOpts, ENV_IMM);
|
||||
|
||||
/*
|
||||
* Check to see if environment variables have disabled presetting.
|
||||
*/
|
||||
if ((pOD != NULL) && ! DISABLED_OPT(pOD))
|
||||
intern_file_load(pOpts);
|
||||
|
||||
/*
|
||||
* ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
|
||||
* variable options. Only the loading of .rc files.
|
||||
*/
|
||||
env_presets(pOpts, ENV_NON_IMM);
|
||||
}
|
||||
pOpts->fOptSet &= ~OPTPROC_PRESETTING;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE
|
||||
*/
|
||||
/*=--subblock=arg=arg_type,arg_name,arg_desc =*/
|
||||
/*=*
|
||||
* library: opts
|
||||
* header: your-opts.h
|
||||
*
|
||||
* lib_description:
|
||||
*
|
||||
* These are the routines that libopts users may call directly from their
|
||||
* code. There are several other routines that can be called by code
|
||||
* generated by the libopts option templates, but they are not to be
|
||||
* called from any other user code. The @file{options.h} header is
|
||||
* fairly clear about this, too.
|
||||
=*/
|
||||
|
||||
/*=export_func optionProcess
|
||||
*
|
||||
* what: this is the main option processing routine
|
||||
*
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + int + argc + program arg count +
|
||||
* arg: + char** + argv + program arg vector +
|
||||
*
|
||||
* ret_type: int
|
||||
* ret_desc: the count of the arguments processed
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This is the main entry point for processing options. It is intended
|
||||
* that this procedure be called once at the beginning of the execution of
|
||||
* a program. Depending on options selected earlier, it is sometimes
|
||||
* necessary to stop and restart option processing, or to select completely
|
||||
* different sets of options. This can be done easily, but you generally
|
||||
* do not want to do this.
|
||||
*
|
||||
* The number of arguments processed always includes the program name.
|
||||
* If one of the arguments is "--", then it is counted and the processing
|
||||
* stops. If an error was encountered and errors are to be tolerated, then
|
||||
* the returned value is the index of the argument causing the error.
|
||||
* A hyphen by itself ("-") will also cause processing to stop and will
|
||||
* @emph{not} be counted among the processed arguments. A hyphen by itself
|
||||
* is treated as an operand. Encountering an operand stops option
|
||||
* processing.
|
||||
*
|
||||
* err: Errors will cause diagnostics to be printed. @code{exit(3)} may
|
||||
* or may not be called. It depends upon whether or not the options
|
||||
* were generated with the "allow-errors" attribute, or if the
|
||||
* ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked.
|
||||
=*/
|
||||
int
|
||||
optionProcess(tOptions * pOpts, int argCt, char ** argVect)
|
||||
{
|
||||
if (! SUCCESSFUL(validate_struct(pOpts, argVect[0])))
|
||||
exit(EX_SOFTWARE);
|
||||
|
||||
/*
|
||||
* Establish the real program name, the program full path,
|
||||
* and do all the presetting the first time thru only.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_INITDONE) == 0) {
|
||||
pOpts->origArgCt = (unsigned int)argCt;
|
||||
pOpts->origArgVect = argVect;
|
||||
pOpts->fOptSet |= OPTPROC_INITDONE;
|
||||
if (HAS_pzPkgDataDir(pOpts))
|
||||
program_pkgdatadir = pOpts->pzPkgDataDir;
|
||||
|
||||
if (! SUCCESSFUL(doPresets(pOpts)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* IF option name conversion was suppressed but it is not suppressed
|
||||
* for the command line, then it's time to translate option names.
|
||||
* Usage text will not get retranslated.
|
||||
*/
|
||||
if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0)
|
||||
&& (pOpts->pTransProc != NULL)
|
||||
&& ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK)
|
||||
== OPTPROC_NXLAT_OPT_CFG) ) {
|
||||
|
||||
pOpts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
|
||||
(*pOpts->pTransProc)();
|
||||
}
|
||||
|
||||
if ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
|
||||
optionSort(pOpts);
|
||||
|
||||
pOpts->curOptIdx = 1;
|
||||
pOpts->pzCurOpt = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF we are (re)starting,
|
||||
* THEN reset option location
|
||||
*/
|
||||
else if (pOpts->curOptIdx <= 0) {
|
||||
pOpts->curOptIdx = 1;
|
||||
pOpts->pzCurOpt = NULL;
|
||||
}
|
||||
|
||||
if (! SUCCESSFUL(regular_opts(pOpts)))
|
||||
return pOpts->origArgCt;
|
||||
|
||||
/*
|
||||
* IF there were no errors
|
||||
* AND we have RC/INI files
|
||||
* AND there is a request to save the files
|
||||
* THEN do that now before testing for conflicts.
|
||||
* (conflicts are ignored in preset options)
|
||||
*/
|
||||
if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
|
||||
&& (pOpts->specOptIdx.save_opts != 0)) {
|
||||
tOptDesc* pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts;
|
||||
|
||||
if (SELECTED_OPT(pOD)) {
|
||||
optionSaveFile(pOpts);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IF we are checking for errors,
|
||||
* THEN look for too few occurrences of required options
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
if (! is_consistent(pOpts))
|
||||
(*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return pOpts->curOptIdx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/autoopts.c */
|
||||
@@ -0,0 +1,335 @@
|
||||
|
||||
/*
|
||||
* \file autoopts.h
|
||||
*
|
||||
* Time-stamp: "2012-03-04 19:05:01 bkorb"
|
||||
*
|
||||
* This file defines all the global structures and special values
|
||||
* used in the automated option processing library.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
#ifndef AUTOGEN_AUTOOPTS_H
|
||||
#define AUTOGEN_AUTOOPTS_H
|
||||
|
||||
#define AO_NAME_LIMIT 127
|
||||
#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1))
|
||||
|
||||
#ifndef AG_PATH_MAX
|
||||
# ifdef PATH_MAX
|
||||
# define AG_PATH_MAX ((size_t)PATH_MAX)
|
||||
# else
|
||||
# define AG_PATH_MAX ((size_t)4096)
|
||||
# endif
|
||||
#else
|
||||
# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN)
|
||||
# undef AG_PATH_MAX
|
||||
# define AG_PATH_MAX ((size_t)PATH_MAX)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef EXPORT
|
||||
#define EXPORT
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# define DIRCH '\\'
|
||||
#else
|
||||
# define DIRCH '/'
|
||||
#endif
|
||||
|
||||
#define AO_EXIT_REQ_USAGE 64
|
||||
#ifndef EX_NOINPUT
|
||||
/**
|
||||
* option state was requested from a file that cannot be loaded.
|
||||
*/
|
||||
# define EX_NOINPUT 66
|
||||
#endif
|
||||
#ifndef EX_SOFTWARE
|
||||
/**
|
||||
* AutoOpts Software failure.
|
||||
*/
|
||||
# define EX_SOFTWARE 70
|
||||
#endif
|
||||
|
||||
#define NL '\n'
|
||||
|
||||
/*
|
||||
* Convert the number to a list usable in a printf call
|
||||
*/
|
||||
#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F
|
||||
|
||||
#define NAMED_OPTS(po) \
|
||||
(((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0)
|
||||
|
||||
#define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0)
|
||||
|
||||
typedef int tDirection;
|
||||
#define DIRECTION_PRESET -1
|
||||
#define DIRECTION_PROCESS 1
|
||||
#define DIRECTION_CALLED 0
|
||||
|
||||
#define PROCESSING(d) ((d)>0)
|
||||
#define PRESETTING(d) ((d)<0)
|
||||
|
||||
/*
|
||||
* When loading a line (or block) of text as an option, the value can
|
||||
* be processed in any of several modes:
|
||||
*
|
||||
* @table @samp
|
||||
* @item keep
|
||||
* Every part of the value between the delimiters is saved.
|
||||
*
|
||||
* @item uncooked
|
||||
* Even if the value begins with quote characters, do not do quote processing.
|
||||
*
|
||||
* @item cooked
|
||||
* If the value looks like a quoted string, then process it.
|
||||
* Double quoted strings are processed the way strings are in "C" programs,
|
||||
* except they are treated as regular characters if the following character
|
||||
* is not a well-established escape sequence.
|
||||
* Single quoted strings (quoted with apostrophies) are handled the way
|
||||
* strings are handled in shell scripts, *except* that backslash escapes
|
||||
* are honored before backslash escapes and apostrophies.
|
||||
* @end table
|
||||
*/
|
||||
typedef enum {
|
||||
OPTION_LOAD_COOKED,
|
||||
OPTION_LOAD_UNCOOKED,
|
||||
OPTION_LOAD_KEEP
|
||||
} tOptionLoadMode;
|
||||
|
||||
static tOptionLoadMode option_load_mode;
|
||||
|
||||
/*
|
||||
* The pager state is used by optionPagedUsage() procedure.
|
||||
* When it runs, it sets itself up to be called again on exit.
|
||||
* If, however, a routine needs a child process to do some work
|
||||
* before it is done, then 'pagerState' must be set to
|
||||
* 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try
|
||||
* to run the pager program before its time.
|
||||
*/
|
||||
typedef enum {
|
||||
PAGER_STATE_INITIAL,
|
||||
PAGER_STATE_READY,
|
||||
PAGER_STATE_CHILD
|
||||
} tePagerState;
|
||||
|
||||
typedef enum {
|
||||
ENV_ALL,
|
||||
ENV_IMM,
|
||||
ENV_NON_IMM
|
||||
} teEnvPresetType;
|
||||
|
||||
typedef enum {
|
||||
TOPT_UNDEFINED = 0,
|
||||
TOPT_SHORT,
|
||||
TOPT_LONG,
|
||||
TOPT_DEFAULT
|
||||
} teOptType;
|
||||
|
||||
typedef struct {
|
||||
tOptDesc* pOD;
|
||||
tCC* pzOptArg;
|
||||
tAoUL flags;
|
||||
teOptType optType;
|
||||
} tOptState;
|
||||
#define OPTSTATE_INITIALIZER(st) \
|
||||
{ NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED }
|
||||
|
||||
#define TEXTTO_TABLE \
|
||||
_TT_(LONGUSAGE) \
|
||||
_TT_(USAGE) \
|
||||
_TT_(VERSION)
|
||||
#define _TT_(n) \
|
||||
TT_ ## n ,
|
||||
|
||||
typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo;
|
||||
|
||||
#undef _TT_
|
||||
|
||||
typedef struct {
|
||||
char const * pzStr;
|
||||
char const * pzReq;
|
||||
char const * pzNum;
|
||||
char const * pzFile;
|
||||
char const * pzKey;
|
||||
char const * pzKeyL;
|
||||
char const * pzBool;
|
||||
char const * pzNest;
|
||||
char const * pzOpt;
|
||||
char const * pzNo;
|
||||
char const * pzBrk;
|
||||
char const * pzNoF;
|
||||
char const * pzSpc;
|
||||
char const * pzOptFmt;
|
||||
char const * pzTime;
|
||||
} arg_types_t;
|
||||
|
||||
#define AGALOC(c, w) ao_malloc((size_t)c)
|
||||
#define AGREALOC(p, c, w) ao_realloc((void*)p, (size_t)c)
|
||||
#define AGFREE(_p) free((void *)_p)
|
||||
#define AGDUPSTR(p, s, w) (p = ao_strdup(s))
|
||||
|
||||
static void *
|
||||
ao_malloc(size_t sz);
|
||||
|
||||
static void *
|
||||
ao_realloc(void *p, size_t sz);
|
||||
|
||||
#define ao_free(_p) free((void *)_p)
|
||||
|
||||
static char *
|
||||
ao_strdup(char const *str);
|
||||
|
||||
/*
|
||||
* DO option handling?
|
||||
*
|
||||
* Options are examined at two times: at immediate handling time and at
|
||||
* normal handling time. If an option is disabled, the timing may be
|
||||
* different from the handling of the undisabled option. The OPTST_DIABLED
|
||||
* bit indicates the state of the currently discovered option.
|
||||
* So, here's how it works:
|
||||
*
|
||||
* A) handling at "immediate" time, either 1 or 2:
|
||||
*
|
||||
* 1. OPTST_DISABLED is not set:
|
||||
* IMM must be set
|
||||
* DISABLE_IMM don't care
|
||||
* TWICE don't care
|
||||
* DISABLE_TWICE don't care
|
||||
* 0 -and- 1 x x x
|
||||
*
|
||||
* 2. OPTST_DISABLED is set:
|
||||
* IMM don't care
|
||||
* DISABLE_IMM must be set
|
||||
* TWICE don't care
|
||||
* DISABLE_TWICE don't care
|
||||
* 1 -and- x 1 x x
|
||||
*/
|
||||
#define DO_IMMEDIATELY(_flg) \
|
||||
( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \
|
||||
|| ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \
|
||||
== (OPTST_DISABLED|OPTST_DISABLE_IMM) ))
|
||||
|
||||
/* B) handling at "regular" time because it was not immediate
|
||||
*
|
||||
* 1. OPTST_DISABLED is not set:
|
||||
* IMM must *NOT* be set
|
||||
* DISABLE_IMM don't care
|
||||
* TWICE don't care
|
||||
* DISABLE_TWICE don't care
|
||||
* 0 -and- 0 x x x
|
||||
*
|
||||
* 2. OPTST_DISABLED is set:
|
||||
* IMM don't care
|
||||
* DISABLE_IMM don't care
|
||||
* TWICE must be set
|
||||
* DISABLE_TWICE don't care
|
||||
* 1 -and- x x 1 x
|
||||
*/
|
||||
#define DO_NORMALLY(_flg) ( \
|
||||
(((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \
|
||||
|| (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \
|
||||
OPTST_DISABLED) )
|
||||
|
||||
/* C) handling at "regular" time because it is to be handled twice.
|
||||
* The immediate bit was already tested and found to be set:
|
||||
*
|
||||
* 3. OPTST_DISABLED is not set:
|
||||
* IMM is set (but don't care)
|
||||
* DISABLE_IMM don't care
|
||||
* TWICE must be set
|
||||
* DISABLE_TWICE don't care
|
||||
* 0 -and- ? x 1 x
|
||||
*
|
||||
* 4. OPTST_DISABLED is set:
|
||||
* IMM don't care
|
||||
* DISABLE_IMM is set (but don't care)
|
||||
* TWICE don't care
|
||||
* DISABLE_TWICE must be set
|
||||
* 1 -and- x ? x 1
|
||||
*/
|
||||
#define DO_SECOND_TIME(_flg) ( \
|
||||
(((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \
|
||||
OPTST_TWICE) \
|
||||
|| (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \
|
||||
(OPTST_DISABLED|OPTST_DISABLE_TWICE) ))
|
||||
|
||||
/*
|
||||
* text_mmap structure. Only active on platforms with mmap(2).
|
||||
*/
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#else
|
||||
# ifndef PROT_READ
|
||||
# define PROT_READ 0x01
|
||||
# endif
|
||||
# ifndef PROT_WRITE
|
||||
# define PROT_WRITE 0x02
|
||||
# endif
|
||||
# ifndef MAP_SHARED
|
||||
# define MAP_SHARED 0x01
|
||||
# endif
|
||||
# ifndef MAP_PRIVATE
|
||||
# define MAP_PRIVATE 0x02
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
# define MAP_FAILED ((void*)-1)
|
||||
#endif
|
||||
|
||||
#ifndef _SC_PAGESIZE
|
||||
# ifdef _SC_PAGE_SIZE
|
||||
# define _SC_PAGESIZE _SC_PAGE_SIZE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRCHR
|
||||
extern char* strchr(char const *s, int c);
|
||||
extern char* strrchr(char const *s, int c);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define and initialize all the user visible strings.
|
||||
* We do not do translations. If translations are to be done, then
|
||||
* the client will provide a callback for that purpose.
|
||||
*/
|
||||
#undef DO_TRANSLATIONS
|
||||
#include "autoopts/usage-txt.h"
|
||||
|
||||
/*
|
||||
* File pointer for usage output
|
||||
*/
|
||||
FILE * option_usage_fp;
|
||||
static char const * program_pkgdatadir;
|
||||
|
||||
extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt;
|
||||
|
||||
#endif /* AUTOGEN_AUTOOPTS_H */
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/autoopts.h */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,50 @@
|
||||
|
||||
#ifndef AUTOGEN_PROJECT_H
|
||||
#define AUTOGEN_PROJECT_H
|
||||
|
||||
#include "config.h"
|
||||
#include "compat/compat.h"
|
||||
#include "ag-char-map.h"
|
||||
|
||||
/*
|
||||
* Procedure success codes
|
||||
*
|
||||
* USAGE: define procedures to return "tSuccess". Test their results
|
||||
* with the SUCCEEDED, FAILED and HADGLITCH macros.
|
||||
*
|
||||
* Microsoft sticks its nose into user space here, so for Windows' sake,
|
||||
* make sure all of these are undefined.
|
||||
*/
|
||||
#undef SUCCESS
|
||||
#undef FAILURE
|
||||
#undef PROBLEM
|
||||
#undef SUCCEEDED
|
||||
#undef SUCCESSFUL
|
||||
#undef FAILED
|
||||
#undef HADGLITCH
|
||||
|
||||
#define SUCCESS ((tSuccess) 0)
|
||||
#define FAILURE ((tSuccess)-1)
|
||||
#define PROBLEM ((tSuccess) 1)
|
||||
|
||||
typedef int tSuccess;
|
||||
|
||||
#define SUCCEEDED(p) ((p) == SUCCESS)
|
||||
#define SUCCESSFUL(p) SUCCEEDED(p)
|
||||
#define FAILED(p) ((p) < SUCCESS)
|
||||
#define HADGLITCH(p) ((p) > SUCCESS)
|
||||
|
||||
#ifndef STR
|
||||
# define __STR(s) #s
|
||||
# define STR(s) __STR(s)
|
||||
#endif
|
||||
|
||||
#ifdef DEFINING
|
||||
# define VALUE(s) = s
|
||||
# define MODE
|
||||
#else
|
||||
# define VALUE(s)
|
||||
# define MODE extern
|
||||
#endif
|
||||
|
||||
#endif /* AUTOGEN_PROJECT_H */
|
||||
@@ -0,0 +1,433 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (usage-txt.h)
|
||||
*
|
||||
* It has been AutoGen-ed May 6, 2012 at 04:21:00 PM by AutoGen 5.16pre36
|
||||
* From the definitions usage-txt.def
|
||||
* and the template file usage-txt.tpl
|
||||
*
|
||||
* This file handles all the bookkeeping required for tracking all the little
|
||||
* tiny strings used by the AutoOpts library. There are 145
|
||||
* of them. This is not versioned because it is entirely internal to the
|
||||
* library and accessed by client code only in a very well-controlled way:
|
||||
* they may substitute translated strings using a procedure that steps through
|
||||
* all the string pointers.
|
||||
*
|
||||
* Copyright (C) 1992-2012 Bruce Korb, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* GNU Lesser General Public License, version 3 or later
|
||||
* <http://gnu.org/licenses/lgpl.html>
|
||||
*
|
||||
* AutoOpts is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AutoOpts is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
#ifndef AUTOOPTS_USAGE_TXT_H_GUARD
|
||||
#define AUTOOPTS_USAGE_TXT_H_GUARD 1
|
||||
|
||||
#undef cch_t
|
||||
#define cch_t char const
|
||||
|
||||
/*
|
||||
* One structure to hold all the pointers to all the stringlets.
|
||||
*/
|
||||
typedef struct {
|
||||
int field_ct;
|
||||
char* utpz_GnuBoolArg;
|
||||
char* utpz_GnuKeyArg;
|
||||
char* utpz_GnuFileArg;
|
||||
char* utpz_GnuKeyLArg;
|
||||
char* utpz_GnuTimeArg;
|
||||
char* utpz_GnuNumArg;
|
||||
char* utpz_GnuStrArg;
|
||||
cch_t* apz_str[ 138 ];
|
||||
} usage_text_t;
|
||||
|
||||
/*
|
||||
* Declare the global structure with all the pointers to translated
|
||||
* strings. This is then used by the usage generation procedure.
|
||||
*/
|
||||
extern usage_text_t option_usage_text;
|
||||
|
||||
#if defined(AUTOOPTS_INTERNAL) /* DEFINE ALL THE STRINGS = = = = = */
|
||||
/*
|
||||
* Provide a mapping from a short name to fields in this structure.
|
||||
*/
|
||||
#define zAO_Alloc (option_usage_text.apz_str[ 0])
|
||||
#define zAO_Bad (option_usage_text.apz_str[ 1])
|
||||
#define zAO_Big (option_usage_text.apz_str[ 2])
|
||||
#define zAO_Err (option_usage_text.apz_str[ 3])
|
||||
#define zAO_Realloc (option_usage_text.apz_str[ 4])
|
||||
#define zAO_Sml (option_usage_text.apz_str[ 5])
|
||||
#define zAO_Strdup (option_usage_text.apz_str[ 6])
|
||||
#define zAO_Ver (option_usage_text.apz_str[ 7])
|
||||
#define zAO_Woops (option_usage_text.apz_str[ 8])
|
||||
#define zAliasRange (option_usage_text.apz_str[ 9])
|
||||
#define zAll (option_usage_text.apz_str[ 10])
|
||||
#define zAlt (option_usage_text.apz_str[ 11])
|
||||
#define zAmbigKey (option_usage_text.apz_str[ 12])
|
||||
#define zAmbigList (option_usage_text.apz_str[ 13])
|
||||
#define zAmbigOptStr (option_usage_text.apz_str[ 14])
|
||||
#define zAmbiguous (option_usage_text.apz_str[ 15])
|
||||
#define zArgsMust (option_usage_text.apz_str[ 16])
|
||||
#define zAtMost (option_usage_text.apz_str[ 17])
|
||||
#define zAuto (option_usage_text.apz_str[ 18])
|
||||
#define zBadPipe (option_usage_text.apz_str[ 19])
|
||||
#define zBadVerArg (option_usage_text.apz_str[ 20])
|
||||
#define zCantFmt (option_usage_text.apz_str[ 21])
|
||||
#define zCantSave (option_usage_text.apz_str[ 22])
|
||||
#define zCfgAO_Flags (option_usage_text.apz_str[ 23])
|
||||
#define zCfgProg (option_usage_text.apz_str[ 24])
|
||||
#define zDefaultOpt (option_usage_text.apz_str[ 25])
|
||||
#define zDis (option_usage_text.apz_str[ 26])
|
||||
#define zDisabledErr (option_usage_text.apz_str[ 27])
|
||||
#define zDisabledOpt (option_usage_text.apz_str[ 28])
|
||||
#define zDisabledWhy (option_usage_text.apz_str[ 29])
|
||||
#define zEnab (option_usage_text.apz_str[ 30])
|
||||
#define zEquiv (option_usage_text.apz_str[ 31])
|
||||
#define zErrOnly (option_usage_text.apz_str[ 32])
|
||||
#define zExamineFmt (option_usage_text.apz_str[ 33])
|
||||
#define zFiveSpaces (option_usage_text.apz_str[ 34])
|
||||
#define zFlagOkay (option_usage_text.apz_str[ 35])
|
||||
#define zFmtFmt (option_usage_text.apz_str[ 36])
|
||||
#define zForkFail (option_usage_text.apz_str[ 37])
|
||||
#define zFreopenFail (option_usage_text.apz_str[ 38])
|
||||
#define zFSErrOptLoad (option_usage_text.apz_str[ 39])
|
||||
#define zFSErrReadFile (option_usage_text.apz_str[ 40])
|
||||
#define zFSOptError (option_usage_text.apz_str[ 41])
|
||||
#define zFSOptErrMayExist (option_usage_text.apz_str[ 42])
|
||||
#define zFSOptErrMustExist (option_usage_text.apz_str[ 43])
|
||||
#define zFSOptErrNoExist (option_usage_text.apz_str[ 44])
|
||||
#define zFSOptErrOpen (option_usage_text.apz_str[ 45])
|
||||
#define zFSOptErrFopen (option_usage_text.apz_str[ 46])
|
||||
#define zFileCannotExist (option_usage_text.apz_str[ 47])
|
||||
#define zFileMustExist (option_usage_text.apz_str[ 48])
|
||||
#define zGenshell (option_usage_text.apz_str[ 49])
|
||||
#define zGnuBoolArg (option_usage_text.utpz_GnuBoolArg)
|
||||
#define zGnuBreak (option_usage_text.apz_str[ 50])
|
||||
#define zGnuKeyArg (option_usage_text.utpz_GnuKeyArg)
|
||||
#define zGnuFileArg (option_usage_text.utpz_GnuFileArg)
|
||||
#define zGnuKeyLArg (option_usage_text.utpz_GnuKeyLArg)
|
||||
#define zGnuTimeArg (option_usage_text.utpz_GnuTimeArg)
|
||||
#define zGnuNestArg (option_usage_text.apz_str[ 51])
|
||||
#define zGnuNumArg (option_usage_text.utpz_GnuNumArg)
|
||||
#define zGnuOptArg (option_usage_text.apz_str[ 52])
|
||||
#define zGnuOptFmt (option_usage_text.apz_str[ 53])
|
||||
#define zGnuStrArg (option_usage_text.utpz_GnuStrArg)
|
||||
#define zIllOptChr (option_usage_text.apz_str[ 54])
|
||||
#define zIllOptStr (option_usage_text.apz_str[ 55])
|
||||
#define zIllVendOptStr (option_usage_text.apz_str[ 56])
|
||||
#define zIntRange (option_usage_text.apz_str[ 57])
|
||||
#define zInvalOptDesc (option_usage_text.apz_str[ 58])
|
||||
#define zLowerBits (option_usage_text.apz_str[ 59])
|
||||
#define zMembers (option_usage_text.apz_str[ 60])
|
||||
#define zMisArg (option_usage_text.apz_str[ 61])
|
||||
#define zMultiEquiv (option_usage_text.apz_str[ 62])
|
||||
#define zMust (option_usage_text.apz_str[ 63])
|
||||
#define zNeedOne (option_usage_text.apz_str[ 64])
|
||||
#define zNoArg (option_usage_text.apz_str[ 65])
|
||||
#define zNoArgs (option_usage_text.apz_str[ 66])
|
||||
#define zNoCreat (option_usage_text.apz_str[ 67])
|
||||
#define zNoFlags (option_usage_text.apz_str[ 68])
|
||||
#define zNoKey (option_usage_text.apz_str[ 69])
|
||||
#define zNoLim (option_usage_text.apz_str[ 70])
|
||||
#define zNoPreset (option_usage_text.apz_str[ 71])
|
||||
#define zNoResetArg (option_usage_text.apz_str[ 72])
|
||||
#define zNoRq_NoShrtTtl (option_usage_text.apz_str[ 73])
|
||||
#define zNoRq_ShrtTtl (option_usage_text.apz_str[ 74])
|
||||
#define zNoStat (option_usage_text.apz_str[ 75])
|
||||
#define zNoState (option_usage_text.apz_str[ 76])
|
||||
#define zNone (option_usage_text.apz_str[ 77])
|
||||
#define zNotDef (option_usage_text.apz_str[ 78])
|
||||
#define zNotCmdOpt (option_usage_text.apz_str[ 79])
|
||||
#define zNotEnough (option_usage_text.apz_str[ 80])
|
||||
#define zNotFile (option_usage_text.apz_str[ 81])
|
||||
#define zNotNumber (option_usage_text.apz_str[ 82])
|
||||
#define zNotDate (option_usage_text.apz_str[ 83])
|
||||
#define zNotDuration (option_usage_text.apz_str[ 84])
|
||||
#define zNrmOptFmt (option_usage_text.apz_str[ 85])
|
||||
#define zNumberOpt (option_usage_text.apz_str[ 86])
|
||||
#define zOnlyOne (option_usage_text.apz_str[ 87])
|
||||
#define zOptsOnly (option_usage_text.apz_str[ 88])
|
||||
#define zOutputFail (option_usage_text.apz_str[ 89])
|
||||
#define zPathFmt (option_usage_text.apz_str[ 90])
|
||||
#define zPlsSendBugs (option_usage_text.apz_str[ 91])
|
||||
#define zPreset (option_usage_text.apz_str[ 92])
|
||||
#define zPresetFile (option_usage_text.apz_str[ 93])
|
||||
#define zPresetIntro (option_usage_text.apz_str[ 94])
|
||||
#define zProhib (option_usage_text.apz_str[ 95])
|
||||
#define zReorder (option_usage_text.apz_str[ 96])
|
||||
#define zRange (option_usage_text.apz_str[ 97])
|
||||
#define zRangeAbove (option_usage_text.apz_str[ 98])
|
||||
#define zRangeLie (option_usage_text.apz_str[ 99])
|
||||
#define zRangeOnly (option_usage_text.apz_str[100])
|
||||
#define zRangeOr (option_usage_text.apz_str[101])
|
||||
#define zRangeErr (option_usage_text.apz_str[102])
|
||||
#define zRangeExact (option_usage_text.apz_str[103])
|
||||
#define zRangeScaled (option_usage_text.apz_str[104])
|
||||
#define zRangeUpto (option_usage_text.apz_str[105])
|
||||
#define zResetNotConfig (option_usage_text.apz_str[106])
|
||||
#define zReqFmt (option_usage_text.apz_str[107])
|
||||
#define zReqOptFmt (option_usage_text.apz_str[108])
|
||||
#define zReqThese (option_usage_text.apz_str[109])
|
||||
#define zReq_NoShrtTtl (option_usage_text.apz_str[110])
|
||||
#define zReq_ShrtTtl (option_usage_text.apz_str[111])
|
||||
#define zSepChars (option_usage_text.apz_str[112])
|
||||
#define zSetMemberSettings (option_usage_text.apz_str[113])
|
||||
#define zShrtGnuOptFmt (option_usage_text.apz_str[114])
|
||||
#define zSixSpaces (option_usage_text.apz_str[115])
|
||||
#define zStdBoolArg (option_usage_text.apz_str[116])
|
||||
#define zStdBreak (option_usage_text.apz_str[117])
|
||||
#define zStdFileArg (option_usage_text.apz_str[118])
|
||||
#define zStdKeyArg (option_usage_text.apz_str[119])
|
||||
#define zStdKeyLArg (option_usage_text.apz_str[120])
|
||||
#define zStdTimeArg (option_usage_text.apz_str[121])
|
||||
#define zStdNestArg (option_usage_text.apz_str[122])
|
||||
#define zStdNoArg (option_usage_text.apz_str[123])
|
||||
#define zStdNumArg (option_usage_text.apz_str[124])
|
||||
#define zStdOptArg (option_usage_text.apz_str[125])
|
||||
#define zStdReqArg (option_usage_text.apz_str[126])
|
||||
#define zStdStrArg (option_usage_text.apz_str[127])
|
||||
#define zTabHyp (option_usage_text.apz_str[128])
|
||||
#define zTabHypAnd (option_usage_text.apz_str[129])
|
||||
#define zTabout (option_usage_text.apz_str[130])
|
||||
#define zThreeSpaces (option_usage_text.apz_str[131])
|
||||
#define zTooLarge (option_usage_text.apz_str[132])
|
||||
#define zTwoSpaces (option_usage_text.apz_str[133])
|
||||
#define zUpTo (option_usage_text.apz_str[134])
|
||||
#define zValidKeys (option_usage_text.apz_str[135])
|
||||
#define zVendOptsAre (option_usage_text.apz_str[136])
|
||||
#define zVendIntro (option_usage_text.apz_str[137])
|
||||
|
||||
/*
|
||||
* First, set up the strings. Some of these are writable. These are all in
|
||||
* English. This gets compiled into libopts and is distributed here so that
|
||||
* xgettext (or equivalents) can extract these strings for translation.
|
||||
*/
|
||||
|
||||
static char eng_zGnuBoolArg[] = "=T/F";
|
||||
static char eng_zGnuKeyArg[] = "=KWd";
|
||||
static char eng_zGnuFileArg[] = "=file";
|
||||
static char eng_zGnuKeyLArg[] = "=Mbr";
|
||||
static char eng_zGnuTimeArg[] = "=Tim";
|
||||
static char eng_zGnuNumArg[] = "=num";
|
||||
static char eng_zGnuStrArg[] = "=str";
|
||||
static char const usage_txt[4631] =
|
||||
/* 0 */ "malloc of %d bytes failed\n\0"
|
||||
/* 27 */ "AutoOpts function called without option descriptor\n\0"
|
||||
/* 79 */ "\tThis exceeds the compiled library version: \0"
|
||||
/* 125 */ "Automated Options Processing Error!\n"
|
||||
"\t%s called AutoOpts function with structure version %d:%d:%d.\n\0"
|
||||
/* 224 */ "realloc of %d bytes at 0x%p failed\n\0"
|
||||
/* 260 */ "\tThis is less than the minimum library version: \0"
|
||||
/* 310 */ "strdup of %d byte string failed\n\0"
|
||||
/* 343 */ "Automated Options version %s\n"
|
||||
"\tcopyright (c) 1999-2012 by Bruce Korb - all rights reserved\n\0"
|
||||
/* 434 */ "AutoOpts lib error: defaulted to option with optional arg\n\0"
|
||||
/* 493 */ "(AutoOpts bug): Aliasing option is out of range.\0"
|
||||
/* 543 */ "all\0"
|
||||
/* 547 */ "\t\t\t\t- an alternate for %s\n\0"
|
||||
/* 574 */ "%s error: the keyword `%s' is ambiguous for %s\n\0"
|
||||
/* 623 */ " The following options match:\n\0"
|
||||
/* 655 */ "%s: ambiguous option name: %s (matches %d options)\n\0"
|
||||
/* 707 */ " %s%s\n\0"
|
||||
/* 715 */ "%s: Command line arguments required\n\0"
|
||||
/* 752 */ "%d %s%s options allowed\n\0"
|
||||
/* 777 */ "version, usage and configuration options:\0"
|
||||
/* 819 */ "Error %d (%s) from the pipe(2) syscall\n\0"
|
||||
/* 859 */ "ERROR: version option argument '%c' invalid. Use:\n"
|
||||
"\t'v' - version only\n"
|
||||
"\t'c' - version and copyright\n"
|
||||
"\t'n' - version and copyright notice\n\0"
|
||||
/* 996 */ "ERROR: %s option conflicts with the %s option\n\0"
|
||||
/* 1044 */ "%s(optionSaveState): error: cannot allocate %d bytes\n\0"
|
||||
/* 1098 */ "auto-options\0"
|
||||
/* 1111 */ "program\0"
|
||||
/* 1119 */ "\t\t\t\t- default option for unnamed options\n\0"
|
||||
/* 1161 */ "\t\t\t\t- disabled as --%s\n\0"
|
||||
/* 1185 */ "%s: The ``%s'' option has been disabled\0"
|
||||
/* 1225 */ " --- %-14s %s\n\0"
|
||||
/* 1240 */ "This option has been disabled\0"
|
||||
/* 1270 */ "\t\t\t\t- enabled by default\n\0"
|
||||
/* 1296 */ "-equivalence\0"
|
||||
/* 1309 */ "ERROR: only \0"
|
||||
/* 1323 */ " - examining environment variables named %s_*\n\0"
|
||||
/* 1370 */ " \0"
|
||||
/* 1376 */ "Options are specified by doubled hyphens and their name or by a single\n"
|
||||
"hyphen and the flag character.\n\0"
|
||||
/* 1479 */ "%%-%ds %%s\n\0"
|
||||
/* 1491 */ "fs error %d (%s) on fork - cannot obtain %s usage\n\0"
|
||||
/* 1542 */ "fs error %d (%s) on freopen\n\0"
|
||||
/* 1571 */ "File error %d (%s) opening %s for loading options\n\0"
|
||||
/* 1622 */ "fs error %d (%s) reading file %s\n\0"
|
||||
/* 1656 */ "fs error %d (%s) on %s %s for option %s\n\0"
|
||||
/* 1697 */ "stat-ing for directory\0"
|
||||
/* 1720 */ "stat-ing for regular file\0"
|
||||
/* 1746 */ "stat-ing for non-existant file\0"
|
||||
/* 1777 */ "open-ing file\0"
|
||||
/* 1791 */ "fopen-ing file\0"
|
||||
/* 1806 */ "\t\t\t\t- file must not pre-exist\n\0"
|
||||
/* 1837 */ "\t\t\t\t- file must pre-exist\n\0"
|
||||
/* 1864 */ "\n"
|
||||
"= = = = = = = =\n\n"
|
||||
"This incarnation of genshell will produce\n"
|
||||
"a shell script to parse the options for %s:\n\n\0"
|
||||
/* 1970 */ "\n"
|
||||
"%s\n\n\0"
|
||||
/* 1976 */ "=Cplx\0"
|
||||
/* 1982 */ "[=arg]\0"
|
||||
/* 1989 */ "--%2$s%1$s\0"
|
||||
/* 2000 */ "%s: illegal option -- %c\n\0"
|
||||
/* 2026 */ "%s: illegal option -- %s\n\0"
|
||||
/* 2052 */ "%s: unknown vendor extension option -- %s\n\0"
|
||||
/* 2095 */ " or an integer from %d through %d\n\0"
|
||||
/* 2131 */ "AutoOpts ERROR: invalid option descriptor for %s\n\0"
|
||||
/* 2182 */ " or an integer mask with any of the lower %d bits set\n\0"
|
||||
/* 2238 */ "\t\t\t\t- is a set membership option\n\0"
|
||||
/* 2272 */ "%s: option `%s' requires an argument\n\0"
|
||||
/* 2310 */ "Equivalenced option '%s' was equivalenced to both\n"
|
||||
"\t'%s' and '%s'\0"
|
||||
/* 2375 */ "\t\t\t\t- must appear between %d and %d times\n\0"
|
||||
/* 2418 */ "ERROR: The %s option is required\n\0"
|
||||
/* 2453 */ "%s: option `%s' cannot have an argument\n\0"
|
||||
/* 2494 */ "%s: Command line arguments not allowed\n\0"
|
||||
/* 2534 */ "error %d (%s) creating %s\n\0"
|
||||
/* 2561 */ "Options are specified by single or double hyphens and their name.\n\0"
|
||||
/* 2628 */ "%s error: `%s' does not match any %s keywords\n\0"
|
||||
/* 2676 */ "\t\t\t\t- may appear multiple times\n\0"
|
||||
/* 2709 */ "\t\t\t\t- may not be preset\n\0"
|
||||
/* 2734 */ "The 'reset-option' option requires an argument\n\0"
|
||||
/* 2782 */ " Arg Option-Name Description\n\0"
|
||||
/* 2817 */ " Flg Arg Option-Name Description\n\0"
|
||||
/* 2855 */ "error %d (%s) stat-ing %s\n\0"
|
||||
/* 2882 */ "%s(optionRestore): error: no saved option state\n\0"
|
||||
/* 2931 */ "none\0"
|
||||
/* 2936 */ "'%s' not defined\n\0"
|
||||
/* 2954 */ "'%s' is not a command line option\n\0"
|
||||
/* 2989 */ "ERROR: The %s option must appear %d times\n\0"
|
||||
/* 3033 */ "error: cannot load options from non-regular file %s\n\0"
|
||||
/* 3087 */ "%s error: `%s' is not a recognizable number\n\0"
|
||||
/* 3133 */ "%s error: `%s' is not a recognizable date/time\n\0"
|
||||
/* 3182 */ "%s error: `%s' is not a recognizable time duration\n\0"
|
||||
/* 3235 */ " %3s %s\0"
|
||||
/* 3243 */ "The '-#<number>' option may omit the hash char\n\0"
|
||||
/* 3291 */ "one %s%s option allowed\n\0"
|
||||
/* 3316 */ "All arguments are named options.\n\0"
|
||||
/* 3350 */ "Write failure to output file\0"
|
||||
/* 3379 */ " - reading file %s\0"
|
||||
/* 3398 */ "\n"
|
||||
"please send bug reports to: %s\n\0"
|
||||
/* 3432 */ "\t\t\t\t- may NOT appear - preset only\n\0"
|
||||
/* 3468 */ "# preset/initialization file\n"
|
||||
"# %s#\n\0"
|
||||
/* 3506 */ "\n"
|
||||
"The following option preset mechanisms are supported:\n\0"
|
||||
/* 3562 */ "prohibits these options:\n\0"
|
||||
/* 3588 */ "Operands and options may be intermixed. They will be reordered.\n\0"
|
||||
/* 3654 */ "%s%ld to %ld\0"
|
||||
/* 3667 */ "%sgreater than or equal to %ld\0"
|
||||
/* 3698 */ "%sIt must lie in one of the ranges:\n\0"
|
||||
/* 3735 */ "%sIt must be in the range:\n\0"
|
||||
/* 3763 */ ", or\n\0"
|
||||
/* 3769 */ "%s error: %s option value %ld is out of range.\n\0"
|
||||
/* 3818 */ "%s%ld exactly\0"
|
||||
/* 3832 */ "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n\0"
|
||||
/* 3878 */ "%sless than or equal to %ld\0"
|
||||
/* 3906 */ "The --reset-option has not been configured.\n\0"
|
||||
/* 3951 */ "ERROR: %s option requires the %s option\n\0"
|
||||
/* 3993 */ " %3s %-14s %s\0"
|
||||
/* 4007 */ "requires these options:\n\0"
|
||||
/* 4032 */ " Arg Option-Name Req? Description\n\0"
|
||||
/* 4072 */ " Flg Arg Option-Name Req? Description\n\0"
|
||||
/* 4115 */ "-_^\0"
|
||||
/* 4119 */ "or you may use a numeric representation. Preceding these with a '!' will\n"
|
||||
"clear the bits, specifying 'none' will clear all bits, and 'all' will set them\n"
|
||||
"all. Multiple entries may be passed as an option argument list.\n\0"
|
||||
/* 4338 */ "%s\0"
|
||||
/* 4341 */ " \0"
|
||||
/* 4348 */ "T/F\0"
|
||||
/* 4352 */ "\n"
|
||||
"%s\n\n"
|
||||
"%s\0"
|
||||
/* 4360 */ "Fil\0"
|
||||
/* 4364 */ "KWd\0"
|
||||
/* 4368 */ "Mbr\0"
|
||||
/* 4372 */ "Tim\0"
|
||||
/* 4376 */ "Cpx\0"
|
||||
/* 4380 */ "no \0"
|
||||
/* 4384 */ "Num\0"
|
||||
/* 4388 */ "opt\0"
|
||||
/* 4392 */ "YES\0"
|
||||
/* 4396 */ "Str\0"
|
||||
/* 4400 */ "\t\t\t\t- \0"
|
||||
/* 4407 */ "\t\t\t\t-- and \0"
|
||||
/* 4419 */ "\t\t\t\t%s\n\0"
|
||||
/* 4427 */ " \0"
|
||||
/* 4431 */ "%s error: %s exceeds %s keyword count\n\0"
|
||||
/* 4471 */ " \0"
|
||||
/* 4474 */ "\t\t\t\t- may appear up to %d times\n\0"
|
||||
/* 4507 */ "The valid \"%s\" option keywords are:\n\0"
|
||||
/* 4544 */ "These additional options are:\0"
|
||||
/* 4574 */ "The next option supports vendor supported extra options:";
|
||||
|
||||
|
||||
/*
|
||||
* Now, define (and initialize) the structure that contains
|
||||
* the pointers to all these strings.
|
||||
* Aren't you glad you don't maintain this by hand?
|
||||
*/
|
||||
usage_text_t option_usage_text = {
|
||||
145,
|
||||
eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuFileArg, eng_zGnuKeyLArg,
|
||||
eng_zGnuTimeArg, eng_zGnuNumArg, eng_zGnuStrArg,
|
||||
{
|
||||
usage_txt + 0, usage_txt + 27, usage_txt + 79, usage_txt + 125,
|
||||
usage_txt + 224, usage_txt + 260, usage_txt + 310, usage_txt + 343,
|
||||
usage_txt + 434, usage_txt + 493, usage_txt + 543, usage_txt + 547,
|
||||
usage_txt + 574, usage_txt + 623, usage_txt + 655, usage_txt + 707,
|
||||
usage_txt + 715, usage_txt + 752, usage_txt + 777, usage_txt + 819,
|
||||
usage_txt + 859, usage_txt + 996, usage_txt +1044, usage_txt +1098,
|
||||
usage_txt +1111, usage_txt +1119, usage_txt +1161, usage_txt +1185,
|
||||
usage_txt +1225, usage_txt +1240, usage_txt +1270, usage_txt +1296,
|
||||
usage_txt +1309, usage_txt +1323, usage_txt +1370, usage_txt +1376,
|
||||
usage_txt +1479, usage_txt +1491, usage_txt +1542, usage_txt +1571,
|
||||
usage_txt +1622, usage_txt +1656, usage_txt +1697, usage_txt +1720,
|
||||
usage_txt +1746, usage_txt +1777, usage_txt +1791, usage_txt +1806,
|
||||
usage_txt +1837, usage_txt +1864, usage_txt +1970, usage_txt +1976,
|
||||
usage_txt +1982, usage_txt +1989, usage_txt +2000, usage_txt +2026,
|
||||
usage_txt +2052, usage_txt +2095, usage_txt +2131, usage_txt +2182,
|
||||
usage_txt +2238, usage_txt +2272, usage_txt +2310, usage_txt +2375,
|
||||
usage_txt +2418, usage_txt +2453, usage_txt +2494, usage_txt +2534,
|
||||
usage_txt +2561, usage_txt +2628, usage_txt +2676, usage_txt +2709,
|
||||
usage_txt +2734, usage_txt +2782, usage_txt +2817, usage_txt +2855,
|
||||
usage_txt +2882, usage_txt +2931, usage_txt +2936, usage_txt +2954,
|
||||
usage_txt +2989, usage_txt +3033, usage_txt +3087, usage_txt +3133,
|
||||
usage_txt +3182, usage_txt +3235, usage_txt +3243, usage_txt +3291,
|
||||
usage_txt +3316, usage_txt +3350, usage_txt +3379, usage_txt +3398,
|
||||
usage_txt +3432, usage_txt +3468, usage_txt +3506, usage_txt +3562,
|
||||
usage_txt +3588, usage_txt +3654, usage_txt +3667, usage_txt +3698,
|
||||
usage_txt +3735, usage_txt +3763, usage_txt +3769, usage_txt +3818,
|
||||
usage_txt +3832, usage_txt +3878, usage_txt +3906, usage_txt +3951,
|
||||
usage_txt +3993, usage_txt +4007, usage_txt +4032, usage_txt +4072,
|
||||
usage_txt +4115, usage_txt +4119, usage_txt +4338, usage_txt +4341,
|
||||
usage_txt +4348, usage_txt +4352, usage_txt +4360, usage_txt +4364,
|
||||
usage_txt +4368, usage_txt +4372, usage_txt +4376, usage_txt +4380,
|
||||
usage_txt +4384, usage_txt +4388, usage_txt +4392, usage_txt +4396,
|
||||
usage_txt +4400, usage_txt +4407, usage_txt +4419, usage_txt +4427,
|
||||
usage_txt +4431, usage_txt +4471, usage_txt +4474, usage_txt +4507,
|
||||
usage_txt +4544, usage_txt +4574
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* DO_TRANSLATIONS */
|
||||
#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */
|
||||
@@ -0,0 +1,94 @@
|
||||
|
||||
/**
|
||||
* \file boolean.c
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:46:19 bkorb"
|
||||
*
|
||||
* Automated Options Paged Usage module.
|
||||
*
|
||||
* This routine will run run-on options through a pager so the
|
||||
* user may examine, print or edit them at their leisure.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*=export_func optionBooleanVal
|
||||
* private:
|
||||
*
|
||||
* what: Decipher a boolean value
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Decipher a true or false value for a boolean valued option argument.
|
||||
* The value is true, unless it starts with 'n' or 'f' or "#f" or
|
||||
* it is an empty string or it is a number that evaluates to zero.
|
||||
=*/
|
||||
void
|
||||
optionBooleanVal(tOptions * pOpts, tOptDesc * pOD )
|
||||
{
|
||||
char* pz;
|
||||
bool res = true;
|
||||
|
||||
(void)pOpts;
|
||||
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0)
|
||||
return;
|
||||
|
||||
if (pOD->optArg.argString == NULL) {
|
||||
pOD->optArg.argBool = false;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (*(pOD->optArg.argString)) {
|
||||
case '0':
|
||||
{
|
||||
long val = strtol( pOD->optArg.argString, &pz, 0 );
|
||||
if ((val != 0) || (*pz != NUL))
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
}
|
||||
case 'N':
|
||||
case 'n':
|
||||
case 'F':
|
||||
case 'f':
|
||||
case NUL:
|
||||
res = false;
|
||||
break;
|
||||
case '#':
|
||||
if (pOD->optArg.argString[1] != 'f')
|
||||
break;
|
||||
res = false;
|
||||
}
|
||||
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
pOD->optArg.argBool = res;
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/boolean.c */
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* @file check.c
|
||||
*
|
||||
* @brief consistency checks.
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:46:35 bkorb"
|
||||
*
|
||||
* This file contains the routines that deal with processing quoted strings
|
||||
* into an internal format.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check for conflicts based on "must" and "cannot" attributes.
|
||||
*/
|
||||
static bool
|
||||
has_conflict(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
if (pOD->pOptMust != NULL) {
|
||||
int const * pMust = pOD->pOptMust;
|
||||
|
||||
while (*pMust != NO_EQUIVALENT) {
|
||||
tOptDesc * p = pOpts->pOptDesc + *(pMust++);
|
||||
if (UNUSED_OPT(p)) {
|
||||
const tOptDesc * pN = pOpts->pOptDesc + pMust[-1];
|
||||
fprintf(stderr, zReqFmt, pOD->pz_Name, pN->pz_Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pOD->pOptCant != NULL) {
|
||||
int const * pCant = pOD->pOptCant;
|
||||
|
||||
while (*pCant != NO_EQUIVALENT) {
|
||||
tOptDesc * p = pOpts->pOptDesc + *(pCant++);
|
||||
if (SELECTED_OPT(p)) {
|
||||
const tOptDesc* pN = pOpts->pOptDesc + pCant[-1];
|
||||
fprintf(stderr, zCantFmt, pOD->pz_Name, pN->pz_Name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the option occurs often enough. Too often is already checked.
|
||||
*/
|
||||
static bool
|
||||
occurs_enough(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
(void)pOpts;
|
||||
|
||||
/*
|
||||
* IF the occurrence counts have been satisfied,
|
||||
* THEN there is no problem.
|
||||
*/
|
||||
if (pOD->optOccCt >= pOD->optMinCt)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* IF MUST_SET means SET and PRESET are okay,
|
||||
* so min occurrence count doesn't count
|
||||
*/
|
||||
if ( (pOD->fOptState & OPTST_MUST_SET)
|
||||
&& (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) )
|
||||
return true;
|
||||
|
||||
if (pOD->optMinCt > 1)
|
||||
fprintf(stderr, zNotEnough, pOD->pz_Name, pOD->optMinCt);
|
||||
else fprintf(stderr, zNeedOne, pOD->pz_Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify option consistency.
|
||||
*
|
||||
* Make sure that the argument list passes our consistency tests.
|
||||
*/
|
||||
LOCAL bool
|
||||
is_consistent(tOptions * pOpts)
|
||||
{
|
||||
tOptDesc * pOD = pOpts->pOptDesc;
|
||||
int oCt = pOpts->presetOptCt;
|
||||
|
||||
/*
|
||||
* FOR each of "oCt" options, ...
|
||||
*/
|
||||
for (;;) {
|
||||
/*
|
||||
* IF the current option was provided on the command line
|
||||
* THEN ensure that any "MUST" requirements are not
|
||||
* "DEFAULT" (unspecified) *AND* ensure that any
|
||||
* "CANT" options have not been SET or DEFINED.
|
||||
*/
|
||||
if (SELECTED_OPT(pOD)) {
|
||||
if (has_conflict(pOpts, pOD))
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF this option is not equivalenced to another,
|
||||
* OR it is equivalenced to itself (is the equiv. root)
|
||||
* THEN we need to make sure it occurs often enough.
|
||||
*/
|
||||
if ( (pOD->optEquivIndex == NO_EQUIVALENT)
|
||||
|| (pOD->optEquivIndex == pOD->optIndex) )
|
||||
|
||||
if (! occurs_enough(pOpts, pOD))
|
||||
return false;
|
||||
|
||||
if (--oCt <= 0)
|
||||
break;
|
||||
pOD++;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF we are stopping on errors, check to see if any remaining
|
||||
* arguments are required to be there or prohibited from being there.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
|
||||
/*
|
||||
* Check for prohibition
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) {
|
||||
if (pOpts->origArgCt > pOpts->curOptIdx) {
|
||||
fprintf(stderr, zNoArgs, pOpts->pzProgName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ELSE not prohibited, check for being required
|
||||
*/
|
||||
else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) {
|
||||
if (pOpts->origArgCt <= pOpts->curOptIdx) {
|
||||
fprintf(stderr, zArgsMust, pOpts->pzProgName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
/* -*- Mode: C -*- */
|
||||
|
||||
/**
|
||||
* \file compat.h --- fake the preprocessor into handlng portability
|
||||
*
|
||||
* Time-stamp: "2012-02-28 19:40:44 bkorb"
|
||||
*
|
||||
* compat.h is free software.
|
||||
* This file is part of AutoGen.
|
||||
*
|
||||
* AutoGen Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoGen is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AutoGen is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* As a special exception, Bruce Korb gives permission for additional
|
||||
* uses of the text contained in the release of compat.h.
|
||||
*
|
||||
* The exception is that, if you link the compat.h library with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the compat.h library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by Bruce Korb under
|
||||
* the name compat.h. If you copy code from other sources under the
|
||||
* General Public License into a copy of compat.h, as the General Public
|
||||
* License permits, the exception does not apply to the code that you add
|
||||
* in this way. To avoid misleading anyone as to the status of such
|
||||
* modified files, you must delete this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for compat.h, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*/
|
||||
#ifndef COMPAT_H_GUARD
|
||||
#define COMPAT_H_GUARD 1
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
|
||||
#elif defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include "windows-config.h"
|
||||
|
||||
#else
|
||||
# error "compat.h" requires "config.h"
|
||||
choke me.
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_STRSIGNAL
|
||||
char * strsignal( int signo );
|
||||
#endif
|
||||
|
||||
#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */
|
||||
#define __USE_GNU 1 /* exact same thing as above */
|
||||
#define __EXTENSIONS__ 1 /* and another way to call for it */
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* SYSTEM HEADERS:
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#if HAVE_SYS_PROCSET_H
|
||||
# include <sys/procset.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if defined( HAVE_SOLARIS_SYSINFO )
|
||||
# include <sys/systeminfo.h>
|
||||
#elif defined( HAVE_UNAME_SYSCALL )
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#ifdef DAEMON_ENABLED
|
||||
# if HAVE_SYS_STROPTS_H
|
||||
# include <sys/stropts.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
# endif
|
||||
|
||||
# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H)
|
||||
# error This system cannot support daemon processing
|
||||
Choke Me.
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_POLL_H
|
||||
# include <sys/poll.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
# endif
|
||||
|
||||
# if HAVE_SYS_UN_H
|
||||
# include <sys/un.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* USER HEADERS:
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* Directory opening stuff:
|
||||
*/
|
||||
# if defined (_POSIX_SOURCE)
|
||||
/* Posix does not require that the d_ino field be present, and some
|
||||
systems do not provide it. */
|
||||
# define REAL_DIR_ENTRY(dp) 1
|
||||
# else /* !_POSIX_SOURCE */
|
||||
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
|
||||
# endif /* !_POSIX_SOURCE */
|
||||
|
||||
# if defined (HAVE_DIRENT_H)
|
||||
# include <dirent.h>
|
||||
# define D_NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
# else /* !HAVE_DIRENT_H */
|
||||
# define dirent direct
|
||||
# define D_NAMLEN(dirent) (dirent)->d_namlen
|
||||
# if defined (HAVE_SYS_NDIR_H)
|
||||
# include <sys/ndir.h>
|
||||
# endif /* HAVE_SYS_NDIR_H */
|
||||
# if defined (HAVE_SYS_DIR_H)
|
||||
# include <sys/dir.h>
|
||||
# endif /* HAVE_SYS_DIR_H */
|
||||
# if defined (HAVE_NDIR_H)
|
||||
# include <ndir.h>
|
||||
# endif /* HAVE_NDIR_H */
|
||||
# endif /* !HAVE_DIRENT_H */
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_FCNTL_H
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
# define O_NONBLOCK FNDELAY
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H)
|
||||
# include <libgen.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIMITS_H) /* this is also in options.h */
|
||||
# include <limits.h>
|
||||
#elif defined(HAVE_SYS_LIMITS_H)
|
||||
# include <sys/limits.h>
|
||||
#endif /* HAVE_LIMITS/SYS_LIMITS_H */
|
||||
|
||||
#include <memory.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
# include <stdint.h>
|
||||
|
||||
#elif defined(HAVE_INTTYPES_H)
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
typedef enum { false = 0, true = 1 } _Bool;
|
||||
# define bool _Bool
|
||||
|
||||
/* The other macros must be usable in preprocessor directives. */
|
||||
# define false 0
|
||||
# define true 1
|
||||
#endif
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* FIXUPS and CONVIENCE STUFF:
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN extern "C"
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* some systems #def errno! and others do not declare it!! */
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Some machines forget this! */
|
||||
|
||||
# ifndef EXIT_FAILURE
|
||||
# define EXIT_SUCCESS 0
|
||||
# define EXIT_FAILURE 1
|
||||
# endif
|
||||
|
||||
#ifndef NUL
|
||||
# define NUL '\0'
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H)
|
||||
# include <sys/param.h>
|
||||
#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */
|
||||
|
||||
#if !defined (MAXPATHLEN) && defined (PATH_MAX)
|
||||
# define MAXPATHLEN PATH_MAX
|
||||
#endif /* !MAXPATHLEN && PATH_MAX */
|
||||
|
||||
#if !defined (MAXPATHLEN) && defined(_MAX_PATH)
|
||||
# define PATH_MAX _MAX_PATH
|
||||
# define MAXPATHLEN _MAX_PATH
|
||||
#endif
|
||||
|
||||
#if !defined (MAXPATHLEN)
|
||||
# define MAXPATHLEN ((size_t)4096)
|
||||
#endif /* MAXPATHLEN */
|
||||
|
||||
#define AG_PATH_MAX ((size_t)MAXPATHLEN)
|
||||
|
||||
#ifndef LONG_MAX
|
||||
# define LONG_MAX ~(1L << (8*sizeof(long) -1))
|
||||
# define INT_MAX ~(1 << (8*sizeof(int) -1))
|
||||
#endif
|
||||
|
||||
#ifndef ULONG_MAX
|
||||
# define ULONG_MAX ~(OUL)
|
||||
# define UINT_MAX ~(OU)
|
||||
#endif
|
||||
|
||||
#ifndef SHORT_MAX
|
||||
# define SHORT_MAX ~(1 << (8*sizeof(short) - 1))
|
||||
#else
|
||||
# define USHORT_MAX ~(OUS)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INT8_T
|
||||
typedef signed char int8_t;
|
||||
# define HAVE_INT8_T 1
|
||||
#endif
|
||||
#ifndef HAVE_UINT8_T
|
||||
typedef unsigned char uint8_t;
|
||||
# define HAVE_UINT8_T 1
|
||||
#endif
|
||||
#ifndef HAVE_INT16_T
|
||||
typedef signed short int16_t;
|
||||
# define HAVE_INT16_T 1
|
||||
#endif
|
||||
#ifndef HAVE_UINT16_T
|
||||
typedef unsigned short uint16_t;
|
||||
# define HAVE_UINT16_T 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INT32_T
|
||||
# if SIZEOF_INT == 4
|
||||
typedef signed int int32_t;
|
||||
# elif SIZEOF_LONG == 4
|
||||
typedef signed long int32_t;
|
||||
# endif
|
||||
# define HAVE_INT32_T 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UINT32_T
|
||||
# if SIZEOF_INT == 4
|
||||
typedef unsigned int uint32_t;
|
||||
# elif SIZEOF_LONG == 4
|
||||
typedef unsigned long uint32_t;
|
||||
# else
|
||||
# error Cannot create a uint32_t type.
|
||||
Choke Me.
|
||||
# endif
|
||||
# define HAVE_UINT32_T 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INTPTR_T
|
||||
# if SIZEOF_CHARP == SIZEOF_LONG
|
||||
typedef signed long intptr_t;
|
||||
# else
|
||||
typedef signed int intptr_t;
|
||||
# endif
|
||||
# define HAVE_INTPTR_T 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UINTPTR_T
|
||||
# if SIZEOF_CHARP == SIZEOF_LONG
|
||||
typedef unsigned long intptr_t;
|
||||
# else
|
||||
typedef unsigned int intptr_t;
|
||||
# endif
|
||||
# define HAVE_INTPTR_T 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_UINT_T
|
||||
typedef unsigned int uint_t;
|
||||
# define HAVE_UINT_T 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SIZE_T
|
||||
typedef unsigned int size_t;
|
||||
# define HAVE_SIZE_T 1
|
||||
#endif
|
||||
#ifndef HAVE_WINT_T
|
||||
typedef unsigned int wint_t;
|
||||
# define HAVE_WINT_T 1
|
||||
#endif
|
||||
#ifndef HAVE_PID_T
|
||||
typedef signed int pid_t;
|
||||
# define HAVE_PID_T 1
|
||||
#endif
|
||||
|
||||
/* redefine these for BSD style string libraries */
|
||||
#ifndef HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
#endif
|
||||
|
||||
#ifdef USE_FOPEN_BINARY
|
||||
# ifndef FOPEN_BINARY_FLAG
|
||||
# define FOPEN_BINARY_FLAG "b"
|
||||
# endif
|
||||
# ifndef FOPEN_TEXT_FLAG
|
||||
# define FOPEN_TEXT_FLAG "t"
|
||||
# endif
|
||||
#else
|
||||
# ifndef FOPEN_BINARY_FLAG
|
||||
# define FOPEN_BINARY_FLAG
|
||||
# endif
|
||||
# ifndef FOPEN_TEXT_FLAG
|
||||
# define FOPEN_TEXT_FLAG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef STR
|
||||
# define _STR(s) #s
|
||||
# define STR(s) _STR(s)
|
||||
#endif
|
||||
|
||||
/* ##### Pointer sized word ##### */
|
||||
|
||||
/* FIXME: the MAX stuff in here is broken! */
|
||||
#if SIZEOF_CHARP > SIZEOF_INT
|
||||
typedef long t_word;
|
||||
#define WORD_MAX LONG_MAX
|
||||
#define WORD_MIN LONG_MIN
|
||||
#else /* SIZEOF_CHARP <= SIZEOF_INT */
|
||||
typedef int t_word;
|
||||
#define WORD_MAX INT_MAX
|
||||
#define WORD_MIN INT_MIN
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_H_GUARD */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of compat/compat.h */
|
||||
@@ -0,0 +1,334 @@
|
||||
/* -*- Mode: C -*- */
|
||||
|
||||
/* pathfind.c --- find a FILE MODE along PATH */
|
||||
|
||||
/*
|
||||
* Author: Gary V Vaughan <gvaughan@oranda.demon.co.uk>
|
||||
* Time-stamp: "2012-03-31 13:44:42 bkorb"
|
||||
*/
|
||||
|
||||
/* Code: */
|
||||
|
||||
#include "compat.h"
|
||||
#ifndef HAVE_PATHFIND
|
||||
#if defined(__windows__) && !defined(__CYGWIN__)
|
||||
char*
|
||||
pathfind( char const* path,
|
||||
char const* fileName,
|
||||
char const* mode )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
||||
static char* make_absolute( char const *string, char const *dot_path );
|
||||
static char* canonicalize_pathname( char *path );
|
||||
static char* extract_colon_unit( char* dir, char const *string, int *p_index );
|
||||
|
||||
|
||||
/*=export_func pathfind
|
||||
*
|
||||
* what: fild a file in a list of directories
|
||||
*
|
||||
* ifndef: HAVE_PATHFIND
|
||||
*
|
||||
* arg: + char const* + path + colon separated list of search directories +
|
||||
* arg: + char const* + file + the name of the file to look for +
|
||||
* arg: + char const* + mode + the mode bits that must be set to match +
|
||||
*
|
||||
* ret_type: char*
|
||||
* ret_desc: the path to the located file
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* pathfind looks for a a file with name "FILE" and "MODE" access
|
||||
* along colon delimited "PATH", and returns the full pathname as a
|
||||
* string, or NULL if not found. If "FILE" contains a slash, then
|
||||
* it is treated as a relative or absolute path and "PATH" is ignored.
|
||||
*
|
||||
* @strong{NOTE}: this function is compiled into @file{libopts} only if
|
||||
* it is not natively supplied.
|
||||
*
|
||||
* The "MODE" argument is a string of option letters chosen from the
|
||||
* list below:
|
||||
* @example
|
||||
* Letter Meaning
|
||||
* r readable
|
||||
* w writable
|
||||
* x executable
|
||||
* f normal file (NOT IMPLEMENTED)
|
||||
* b block special (NOT IMPLEMENTED)
|
||||
* c character special (NOT IMPLEMENTED)
|
||||
* d directory (NOT IMPLEMENTED)
|
||||
* p FIFO (pipe) (NOT IMPLEMENTED)
|
||||
* u set user ID bit (NOT IMPLEMENTED)
|
||||
* g set group ID bit (NOT IMPLEMENTED)
|
||||
* k sticky bit (NOT IMPLEMENTED)
|
||||
* s size nonzero (NOT IMPLEMENTED)
|
||||
* @end example
|
||||
*
|
||||
* example:
|
||||
* To find the "ls" command using the "PATH" environment variable:
|
||||
* @example
|
||||
* #include <stdlib.h>
|
||||
* char* pz_ls = pathfind( getenv("PATH"), "ls", "rx" );
|
||||
* <<do whatever with pz_ls>>
|
||||
* free( pz_ls );
|
||||
* @end example
|
||||
* The path is allocated with @code{malloc(3C)}, so you must @code{free(3C)}
|
||||
* the result. Also, do not use unimplemented file modes. :-)
|
||||
*
|
||||
* err: returns NULL if the file is not found.
|
||||
=*/
|
||||
char*
|
||||
pathfind( char const* path,
|
||||
char const* fileName,
|
||||
char const* mode )
|
||||
{
|
||||
int p_index = 0;
|
||||
int mode_bits = 0;
|
||||
char* pathName = NULL;
|
||||
char zPath[ AG_PATH_MAX + 1 ];
|
||||
|
||||
if (strchr( mode, 'r' )) mode_bits |= R_OK;
|
||||
if (strchr( mode, 'w' )) mode_bits |= W_OK;
|
||||
if (strchr( mode, 'x' )) mode_bits |= X_OK;
|
||||
|
||||
/*
|
||||
* FOR each non-null entry in the colon-separated path, DO ...
|
||||
*/
|
||||
for (;;) {
|
||||
DIR* dirP;
|
||||
char* colon_unit = extract_colon_unit( zPath, path, &p_index );
|
||||
|
||||
/*
|
||||
* IF no more entries, THEN quit
|
||||
*/
|
||||
if (colon_unit == NULL)
|
||||
break;
|
||||
|
||||
dirP = opendir( colon_unit );
|
||||
|
||||
/*
|
||||
* IF the directory is inaccessable, THEN next directory
|
||||
*/
|
||||
if (dirP == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* FOR every entry in the given directory, ...
|
||||
*/
|
||||
for (;;) {
|
||||
struct dirent *entP = readdir( dirP );
|
||||
|
||||
if (entP == (struct dirent*)NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* IF the file name matches the one we are looking for, ...
|
||||
*/
|
||||
if (strcmp( entP->d_name, fileName ) == 0) {
|
||||
char* pzFullName = make_absolute( fileName, colon_unit);
|
||||
|
||||
/*
|
||||
* Make sure we can access it in the way we want
|
||||
*/
|
||||
if (access( pzFullName, mode_bits ) >= 0) {
|
||||
/*
|
||||
* We can, so normalize the name and return it below
|
||||
*/
|
||||
pathName = canonicalize_pathname( pzFullName );
|
||||
}
|
||||
|
||||
free( (void*)pzFullName );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir( dirP );
|
||||
|
||||
if (pathName != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
return pathName;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn STRING (a pathname) into an absolute pathname, assuming that
|
||||
* DOT_PATH contains the symbolic location of `.'. This always returns
|
||||
* a new string, even if STRING was an absolute pathname to begin with.
|
||||
*/
|
||||
static char*
|
||||
make_absolute( char const *string, char const *dot_path )
|
||||
{
|
||||
char *result;
|
||||
int result_len;
|
||||
|
||||
if (!dot_path || *string == '/') {
|
||||
result = strdup( string );
|
||||
} else {
|
||||
if (dot_path && dot_path[0]) {
|
||||
result = malloc( 2 + strlen( dot_path ) + strlen( string ) );
|
||||
strcpy( result, dot_path );
|
||||
result_len = strlen( result );
|
||||
if (result[result_len - 1] != '/') {
|
||||
result[result_len++] = '/';
|
||||
result[result_len] = '\0';
|
||||
}
|
||||
} else {
|
||||
result = malloc( 3 + strlen( string ) );
|
||||
result[0] = '.'; result[1] = '/'; result[2] = '\0';
|
||||
result_len = 2;
|
||||
}
|
||||
|
||||
strcpy( result + result_len, string );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Canonicalize PATH, and return a new path. The new path differs from
|
||||
* PATH in that:
|
||||
*
|
||||
* Multiple `/'s are collapsed to a single `/'.
|
||||
* Leading `./'s are removed.
|
||||
* Trailing `/.'s are removed.
|
||||
* Trailing `/'s are removed.
|
||||
* Non-leading `../'s and trailing `..'s are handled by removing
|
||||
* portions of the path.
|
||||
*/
|
||||
static char*
|
||||
canonicalize_pathname( char *path )
|
||||
{
|
||||
int i, start;
|
||||
char stub_char, *result;
|
||||
|
||||
/* The result cannot be larger than the input PATH. */
|
||||
result = strdup( path );
|
||||
|
||||
stub_char = (*path == '/') ? '/' : '.';
|
||||
|
||||
/* Walk along RESULT looking for things to compact. */
|
||||
i = 0;
|
||||
while (result[i]) {
|
||||
while (result[i] != '\0' && result[i] != '/')
|
||||
i++;
|
||||
|
||||
start = i++;
|
||||
|
||||
/* If we didn't find any slashes, then there is nothing left to
|
||||
* do.
|
||||
*/
|
||||
if (!result[start])
|
||||
break;
|
||||
|
||||
/* Handle multiple `/'s in a row. */
|
||||
while (result[i] == '/')
|
||||
i++;
|
||||
|
||||
#if !defined (apollo)
|
||||
if ((start + 1) != i)
|
||||
#else
|
||||
if ((start + 1) != i && (start != 0 || i != 2))
|
||||
#endif /* apollo */
|
||||
{
|
||||
strcpy( result + start + 1, result + i );
|
||||
i = start + 1;
|
||||
}
|
||||
|
||||
/* Handle backquoted `/'. */
|
||||
if (start > 0 && result[start - 1] == '\\')
|
||||
continue;
|
||||
|
||||
/* Check for trailing `/', and `.' by itself. */
|
||||
if ((start && !result[i])
|
||||
|| (result[i] == '.' && !result[i+1])) {
|
||||
result[--i] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for `../', `./' or trailing `.' by itself. */
|
||||
if (result[i] == '.') {
|
||||
/* Handle `./'. */
|
||||
if (result[i + 1] == '/') {
|
||||
strcpy( result + i, result + i + 1 );
|
||||
i = (start < 0) ? 0 : start;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle `../' or trailing `..' by itself. */
|
||||
if (result[i + 1] == '.' &&
|
||||
(result[i + 2] == '/' || !result[i + 2])) {
|
||||
while (--start > -1 && result[start] != '/')
|
||||
;
|
||||
strcpy( result + start + 1, result + i + 2 );
|
||||
i = (start < 0) ? 0 : start;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!*result) {
|
||||
*result = stub_char;
|
||||
result[1] = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a string containing units of information separated by colons,
|
||||
* return the next one pointed to by (P_INDEX), or NULL if there are no
|
||||
* more. Advance (P_INDEX) to the character after the colon.
|
||||
*/
|
||||
static char*
|
||||
extract_colon_unit( char* pzDir, char const *string, int *p_index )
|
||||
{
|
||||
char* pzDest = pzDir;
|
||||
int ix = *p_index;
|
||||
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((unsigned)ix >= strlen( string ))
|
||||
return NULL;
|
||||
|
||||
{
|
||||
char const* pzSrc = string + ix;
|
||||
|
||||
while (*pzSrc == ':') pzSrc++;
|
||||
|
||||
for (;;) {
|
||||
char ch = (*(pzDest++) = *(pzSrc++));
|
||||
switch (ch) {
|
||||
case ':':
|
||||
pzDest[-1] = NUL;
|
||||
case NUL:
|
||||
goto copy_done;
|
||||
}
|
||||
|
||||
if ((unsigned long)(pzDest - pzDir) >= AG_PATH_MAX)
|
||||
break;
|
||||
} copy_done:;
|
||||
|
||||
ix = pzSrc - string;
|
||||
}
|
||||
|
||||
if (*pzDir == NUL)
|
||||
return NULL;
|
||||
|
||||
*p_index = ix;
|
||||
return pzDir;
|
||||
}
|
||||
#endif /* __windows__ / __CYGWIN__ */
|
||||
#endif /* HAVE_PATHFIND */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of compat/pathfind.c */
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
#ifndef HAVE_VPRINTF
|
||||
#include "choke-me: no vprintf and no snprintf"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_STDARG_H)
|
||||
# include <stdarg.h>
|
||||
# ifndef VA_START
|
||||
# define VA_START(a, f) va_start(a, f)
|
||||
# define VA_END(a) va_end(a)
|
||||
# endif /* VA_START */
|
||||
# define SNV_USING_STDARG_H
|
||||
|
||||
#elif defined(HAVE_VARARGS_H)
|
||||
# include <varargs.h>
|
||||
# ifndef VA_START
|
||||
# define VA_START(a, f) va_start(a)
|
||||
# define VA_END(a) va_end(a)
|
||||
# endif /* VA_START */
|
||||
# undef SNV_USING_STDARG_H
|
||||
|
||||
#else
|
||||
# include "must-have-stdarg-or-varargs"
|
||||
#endif
|
||||
|
||||
static int
|
||||
snprintf(char *str, size_t n, char const *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rval;
|
||||
|
||||
#ifdef VSPRINTF_CHARSTAR
|
||||
char *rp;
|
||||
VA_START(ap, fmt);
|
||||
rp = vsprintf(str, fmt, ap);
|
||||
VA_END(ap);
|
||||
rval = strlen(rp);
|
||||
|
||||
#else
|
||||
VA_START(ap, fmt);
|
||||
rval = vsprintf(str, fmt, ap);
|
||||
VA_END(ap);
|
||||
#endif
|
||||
|
||||
if (rval > n) {
|
||||
fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n);
|
||||
abort();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int
|
||||
vsnprintf( char *str, size_t n, char const *fmt, va_list ap )
|
||||
{
|
||||
#ifdef VSPRINTF_CHARSTAR
|
||||
return (strlen(vsprintf(str, fmt, ap)));
|
||||
#else
|
||||
return (vsprintf(str, fmt, ap));
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
SYNOPSIS
|
||||
#include <string.h>
|
||||
|
||||
char *strchr(char const *s, int c);
|
||||
|
||||
char *strrchr(char const *s, int c);
|
||||
|
||||
DESCRIPTION
|
||||
The strchr() function returns a pointer to the first occurrence of the
|
||||
character c in the string s.
|
||||
|
||||
The strrchr() function returns a pointer to the last occurrence of the
|
||||
character c in the string s.
|
||||
|
||||
Here "character" means "byte" - these functions do not work with wide
|
||||
or multi-byte characters.
|
||||
|
||||
RETURN VALUE
|
||||
The strchr() and strrchr() functions return a pointer to the matched
|
||||
character or NULL if the character is not found.
|
||||
|
||||
CONFORMING TO
|
||||
SVID 3, POSIX, BSD 4.3, ISO 9899
|
||||
*/
|
||||
|
||||
char*
|
||||
strchr( char const *s, int c)
|
||||
{
|
||||
do {
|
||||
if ((unsigned)*s == (unsigned)c)
|
||||
return s;
|
||||
|
||||
} while (*(++s) != NUL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char*
|
||||
strrchr( char const *s, int c)
|
||||
{
|
||||
char const *e = s + strlen(s);
|
||||
|
||||
for (;;) {
|
||||
if (--e < s)
|
||||
break;
|
||||
|
||||
if ((unsigned)*e == (unsigned)c)
|
||||
return e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of compat/strsignal.c */
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Platforms without strdup ?!?!?!
|
||||
*/
|
||||
|
||||
static char *
|
||||
strdup( char const *s )
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup");
|
||||
|
||||
if (cp != NULL)
|
||||
(void) strcpy(cp, s);
|
||||
|
||||
return cp;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
|
||||
/*
|
||||
* Time-stamp: "2010-02-24 08:39:04 bkorb"
|
||||
*
|
||||
* This file is part of AutoGen.
|
||||
*
|
||||
* AutoGen Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoGen is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AutoGen is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef WINDOWS_CONFIG_HACKERY
|
||||
#define WINDOWS_CONFIG_HACKERY 1
|
||||
|
||||
/*
|
||||
* The definitions below have been stolen from NTP's config.h for Windows.
|
||||
* However, they may be kept here in order to keep libopts independent from
|
||||
* the NTP project.
|
||||
*/
|
||||
#ifndef __windows__
|
||||
# define __windows__ 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Miscellaneous functions that Microsoft maps
|
||||
* to other names
|
||||
*
|
||||
* #define inline __inline
|
||||
* #define vsnprintf _vsnprintf
|
||||
*/
|
||||
#define snprintf _snprintf
|
||||
/*
|
||||
* #define stricmp _stricmp
|
||||
* #define strcasecmp _stricmp
|
||||
* #define isascii __isascii
|
||||
* #define finite _finite
|
||||
* #define random rand
|
||||
* #define srandom srand
|
||||
*/
|
||||
|
||||
#define SIZEOF_INT 4
|
||||
#define SIZEOF_CHARP 4
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_SHORT 2
|
||||
|
||||
typedef unsigned long uintptr_t;
|
||||
|
||||
/*
|
||||
* # define HAVE_NET_IF_H
|
||||
* # define QSORT_USES_VOID_P
|
||||
* # define HAVE_SETVBUF
|
||||
* # define HAVE_VSPRINTF
|
||||
* # define HAVE_SNPRINTF
|
||||
* # define HAVE_VSNPRINTF
|
||||
* # define HAVE_PROTOTYPES /* from ntpq.mak * /
|
||||
* # define HAVE_MEMMOVE
|
||||
* # define HAVE_TERMIOS_H
|
||||
* # define HAVE_ERRNO_H
|
||||
* # define HAVE_STDARG_H
|
||||
* # define HAVE_NO_NICE
|
||||
* # define HAVE_MKTIME
|
||||
* # define TIME_WITH_SYS_TIME
|
||||
* # define HAVE_IO_COMPLETION_PORT
|
||||
* # define ISC_PLATFORM_NEEDNTOP
|
||||
* # define ISC_PLATFORM_NEEDPTON
|
||||
* # define NEED_S_CHAR_TYPEDEF
|
||||
* # define USE_PROTOTYPES /* for ntp_types.h * /
|
||||
*
|
||||
* #define ULONG_CONST(a) a ## UL
|
||||
*/
|
||||
|
||||
#define HAVE_LIMITS_H 1
|
||||
#define HAVE_STRDUP 1
|
||||
#define HAVE_STRCHR 1
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/*
|
||||
* VS.NET's version of wspiapi.h has a bug in it
|
||||
* where it assigns a value to a variable inside
|
||||
* an if statement. It should be comparing them.
|
||||
* We prevent inclusion since we are not using this
|
||||
* code so we don't have to see the warning messages
|
||||
*/
|
||||
#ifndef _WSPIAPI_H_
|
||||
#define _WSPIAPI_H_
|
||||
#endif
|
||||
|
||||
/* Prevent inclusion of winsock.h in windows.h */
|
||||
#ifndef _WINSOCKAPI_
|
||||
#define _WINSOCKAPI_
|
||||
#endif
|
||||
|
||||
#ifndef __RPCASYNC_H__
|
||||
#define __RPCASYNC_H__
|
||||
#endif
|
||||
|
||||
/* Include Windows headers */
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* Compatibility declarations for Windows, assuming SYS_WINNT
|
||||
* has been defined.
|
||||
*/
|
||||
#define strdup _strdup
|
||||
#define stat _stat /* struct stat from <sys/stat.h> */
|
||||
#define unlink _unlink
|
||||
#define fchmod( _x, _y );
|
||||
#define ssize_t SSIZE_T
|
||||
|
||||
#include <io.h>
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define read _read
|
||||
#define write _write
|
||||
#define lseek _lseek
|
||||
#define pipe _pipe
|
||||
#define dup2 _dup2
|
||||
|
||||
#define O_RDWR _O_RDWR
|
||||
#define O_RDONLY _O_RDONLY
|
||||
#define O_EXCL _O_EXCL
|
||||
|
||||
#ifndef S_ISREG
|
||||
# define S_IFREG _S_IFREG
|
||||
# define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG)
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
# define S_IFDIR _S_IFDIR
|
||||
# define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#endif /* WINDOWS_CONFIG_HACKERY */
|
||||
File diff suppressed because it is too large
Load Diff
+311
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* \file cook.c
|
||||
*
|
||||
* Time-stamp: "2012-02-28 19:40:47 bkorb"
|
||||
*
|
||||
* This file contains the routines that deal with processing quoted strings
|
||||
* into an internal format.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static bool
|
||||
contiguous_quote(char ** pps, char * pq, int * lnct_p);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/*=export_func ao_string_cook_escape_char
|
||||
* private:
|
||||
*
|
||||
* what: escape-process a string fragment
|
||||
* arg: + char const* + pzScan + points to character after the escape +
|
||||
* arg: + char* + pRes + Where to put the result byte +
|
||||
* arg: + unsigned int + nl_ch + replacement char if scanned char is \n +
|
||||
*
|
||||
* ret-type: unsigned int
|
||||
* ret-desc: The number of bytes consumed processing the escaped character.
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This function converts "t" into "\t" and all your other favorite
|
||||
* escapes, including numeric ones: hex and ocatal, too.
|
||||
* The returned result tells the caller how far to advance the
|
||||
* scan pointer (passed in). The default is to just pass through the
|
||||
* escaped character and advance the scan by one.
|
||||
*
|
||||
* Some applications need to keep an escaped newline, others need to
|
||||
* suppress it. This is accomplished by supplying a '\n' replacement
|
||||
* character that is different from \n, if need be. For example, use
|
||||
* 0x7F and never emit a 0x7F.
|
||||
*
|
||||
* err: @code{NULL} is returned if the string is mal-formed.
|
||||
=*/
|
||||
unsigned int
|
||||
ao_string_cook_escape_char(char const* pzIn, char* pRes, uint_t nl)
|
||||
{
|
||||
unsigned int res = 1;
|
||||
|
||||
switch (*pRes = *pzIn++) {
|
||||
case NUL: /* NUL - end of input string */
|
||||
return 0;
|
||||
case '\r':
|
||||
if (*pzIn != NL)
|
||||
return 1;
|
||||
res++;
|
||||
/* FALLTHROUGH */
|
||||
case NL: /* NL - emit newline */
|
||||
*pRes = (char)nl;
|
||||
return res;
|
||||
|
||||
case 'a': *pRes = '\a'; break;
|
||||
case 'b': *pRes = '\b'; break;
|
||||
case 'f': *pRes = '\f'; break;
|
||||
case 'n': *pRes = NL; break;
|
||||
case 'r': *pRes = '\r'; break;
|
||||
case 't': *pRes = '\t'; break;
|
||||
case 'v': *pRes = '\v'; break;
|
||||
|
||||
case 'x':
|
||||
case 'X': /* HEX Escape */
|
||||
if (IS_HEX_DIGIT_CHAR(*pzIn)) {
|
||||
char z[4], *pz = z;
|
||||
|
||||
do *(pz++) = *(pzIn++);
|
||||
while (IS_HEX_DIGIT_CHAR(*pzIn) && (pz < z + 2));
|
||||
*pz = NUL;
|
||||
*pRes = (unsigned char)strtoul(z, NULL, 16);
|
||||
res += pz - z;
|
||||
}
|
||||
break;
|
||||
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
{
|
||||
/*
|
||||
* IF the character copied was an octal digit,
|
||||
* THEN set the output character to an octal value
|
||||
*/
|
||||
char z[4], *pz = z + 1;
|
||||
unsigned long val;
|
||||
z[0] = *pRes;
|
||||
|
||||
while (IS_OCT_DIGIT_CHAR(*pzIn) && (pz < z + 3))
|
||||
*(pz++) = *(pzIn++);
|
||||
*pz = NUL;
|
||||
val = strtoul(z, NULL, 8);
|
||||
if (val > 0xFF)
|
||||
val = 0xFF;
|
||||
*pRes = (unsigned char)val;
|
||||
res = pz - z;
|
||||
break;
|
||||
}
|
||||
|
||||
default: ;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* A quoted string has been found.
|
||||
* Find the end of it and compress any escape sequences.
|
||||
*/
|
||||
static bool
|
||||
contiguous_quote(char ** pps, char * pq, int * lnct_p)
|
||||
{
|
||||
char * ps = *pps + 1;
|
||||
|
||||
for (;;) {
|
||||
while (IS_WHITESPACE_CHAR(*ps))
|
||||
if (*(ps++) == NL)
|
||||
(*lnct_p)++;
|
||||
|
||||
/*
|
||||
* IF the next character is a quote character,
|
||||
* THEN we will concatenate the strings.
|
||||
*/
|
||||
switch (*ps) {
|
||||
case '"':
|
||||
case '\'':
|
||||
*pq = *(ps++); /* assign new quote character and return */
|
||||
*pps = ps;
|
||||
return true;
|
||||
|
||||
case '/':
|
||||
/*
|
||||
* Allow for a comment embedded in the concatenated string.
|
||||
*/
|
||||
switch (ps[1]) {
|
||||
default:
|
||||
*pps = NULL;
|
||||
return false;
|
||||
|
||||
case '/':
|
||||
/*
|
||||
* Skip to end of line
|
||||
*/
|
||||
ps = strchr(ps, NL);
|
||||
if (ps == NULL) {
|
||||
*pps = NULL;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case '*':
|
||||
{
|
||||
char* p = strstr( ps+2, "*/" );
|
||||
/*
|
||||
* Skip to terminating star slash
|
||||
*/
|
||||
if (p == NULL) {
|
||||
*pps = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (ps < p) {
|
||||
if (*(ps++) == NL)
|
||||
(*lnct_p)++;
|
||||
}
|
||||
|
||||
ps = p + 2;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
/*
|
||||
* The next non-whitespace character is not a quote.
|
||||
* The series of quoted strings has come to an end.
|
||||
*/
|
||||
*pps = ps;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*=export_func ao_string_cook
|
||||
* private:
|
||||
*
|
||||
* what: concatenate and escape-process strings
|
||||
* arg: + char* + pzScan + The *MODIFIABLE* input buffer +
|
||||
* arg: + int* + lnct_p + The (possibly NULL) pointer to a line count +
|
||||
*
|
||||
* ret-type: char*
|
||||
* ret-desc: The address of the text following the processed strings.
|
||||
* The return value is NULL if the strings are ill-formed.
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* A series of one or more quoted strings are concatenated together.
|
||||
* If they are quoted with double quotes (@code{"}), then backslash
|
||||
* escapes are processed per the C programming language. If they are
|
||||
* single quote strings, then the backslashes are honored only when they
|
||||
* precede another backslash or a single quote character.
|
||||
*
|
||||
* err: @code{NULL} is returned if the string(s) is/are mal-formed.
|
||||
=*/
|
||||
char *
|
||||
ao_string_cook(char * pzScan, int * lnct_p)
|
||||
{
|
||||
int l = 0;
|
||||
char q = *pzScan;
|
||||
|
||||
/*
|
||||
* It is a quoted string. Process the escape sequence characters
|
||||
* (in the set "abfnrtv") and make sure we find a closing quote.
|
||||
*/
|
||||
char* pzD = pzScan++;
|
||||
char* pzS = pzScan;
|
||||
|
||||
if (lnct_p == NULL)
|
||||
lnct_p = &l;
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
* IF the next character is the quote character, THEN we may end the
|
||||
* string. We end it unless the next non-blank character *after* the
|
||||
* string happens to also be a quote. If it is, then we will change
|
||||
* our quote character to the new quote character and continue
|
||||
* condensing text.
|
||||
*/
|
||||
while (*pzS == q) {
|
||||
*pzD = NUL; /* This is probably the end of the line */
|
||||
if (! contiguous_quote(&pzS, &q, lnct_p))
|
||||
return pzS;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are inside a quoted string. Copy text.
|
||||
*/
|
||||
switch (*(pzD++) = *(pzS++)) {
|
||||
case NUL:
|
||||
return NULL;
|
||||
|
||||
case NL:
|
||||
(*lnct_p)++;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
/*
|
||||
* IF we are escaping a new line,
|
||||
* THEN drop both the escape and the newline from
|
||||
* the result string.
|
||||
*/
|
||||
if (*pzS == NL) {
|
||||
pzS++;
|
||||
pzD--;
|
||||
(*lnct_p)++;
|
||||
}
|
||||
|
||||
/*
|
||||
* ELSE IF the quote character is '"' or '`',
|
||||
* THEN we do the full escape character processing
|
||||
*/
|
||||
else if (q != '\'') {
|
||||
int ct = ao_string_cook_escape_char(pzS, pzD-1, (uint_t)NL);
|
||||
if (ct == 0)
|
||||
return NULL;
|
||||
|
||||
pzS += ct;
|
||||
} /* if (q != '\'') */
|
||||
|
||||
/*
|
||||
* OTHERWISE, we only process "\\", "\'" and "\#" sequences.
|
||||
* The latter only to easily hide preprocessing directives.
|
||||
*/
|
||||
else switch (*pzS) {
|
||||
case '\\':
|
||||
case '\'':
|
||||
case '#':
|
||||
pzD[-1] = *pzS++;
|
||||
}
|
||||
} /* switch (*(pzD++) = *(pzS++)) */
|
||||
} /* for (;;) */
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/cook.c */
|
||||
+543
@@ -0,0 +1,543 @@
|
||||
|
||||
/**
|
||||
* \file enumeration.c
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:22:33 bkorb"
|
||||
*
|
||||
* Automated Options Paged Usage module.
|
||||
*
|
||||
* This routine will run run-on options through a pager so the
|
||||
* user may examine, print or edit them at their leisure.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
static char const * pz_enum_err_fmt;
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static void
|
||||
enum_err(tOptions * pOpts, tOptDesc * pOD,
|
||||
char const * const * paz_names, int name_ct);
|
||||
|
||||
static uintptr_t
|
||||
find_name(char const * pzName, tOptions * pOpts, tOptDesc * pOD,
|
||||
char const * const * paz_names, unsigned int name_ct);
|
||||
|
||||
static void
|
||||
set_memb_usage(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
|
||||
unsigned int name_ct);
|
||||
|
||||
static void
|
||||
set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
|
||||
unsigned int name_ct);
|
||||
|
||||
static void
|
||||
set_memb_names(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
|
||||
unsigned int name_ct);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
static void
|
||||
enum_err(tOptions * pOpts, tOptDesc * pOD,
|
||||
char const * const * paz_names, int name_ct)
|
||||
{
|
||||
size_t max_len = 0;
|
||||
size_t ttl_len = 0;
|
||||
int ct_down = name_ct;
|
||||
int hidden = 0;
|
||||
|
||||
/*
|
||||
* A real "pOpts" pointer means someone messed up. Give a real error.
|
||||
*/
|
||||
if (pOpts > OPTPROC_EMIT_LIMIT)
|
||||
fprintf(option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName,
|
||||
pOD->optArg.argString, pOD->pz_Name);
|
||||
|
||||
fprintf(option_usage_fp, zValidKeys, pOD->pz_Name);
|
||||
|
||||
/*
|
||||
* If the first name starts with this funny character, then we have
|
||||
* a first value with an unspellable name. You cannot specify it.
|
||||
* So, we don't list it either.
|
||||
*/
|
||||
if (**paz_names == 0x7F) {
|
||||
paz_names++;
|
||||
hidden = 1;
|
||||
ct_down = --name_ct;
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out the maximum length of any name, plus the total length
|
||||
* of all the names.
|
||||
*/
|
||||
{
|
||||
char const * const * paz = paz_names;
|
||||
|
||||
do {
|
||||
size_t len = strlen(*(paz++)) + 1;
|
||||
if (len > max_len)
|
||||
max_len = len;
|
||||
ttl_len += len;
|
||||
} while (--ct_down > 0);
|
||||
|
||||
ct_down = name_ct;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF any one entry is about 1/2 line or longer, print one per line
|
||||
*/
|
||||
if (max_len > 35) {
|
||||
do {
|
||||
fprintf(option_usage_fp, ENUM_ERR_SEP_LINE_FMT, *(paz_names++));
|
||||
} while (--ct_down > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ELSE IF they all fit on one line, then do so.
|
||||
*/
|
||||
else if (ttl_len < 76) {
|
||||
fputc(' ', option_usage_fp);
|
||||
do {
|
||||
fputc(' ', option_usage_fp);
|
||||
fputs(*(paz_names++), option_usage_fp);
|
||||
} while (--ct_down > 0);
|
||||
fputc(NL, option_usage_fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise, columnize the output
|
||||
*/
|
||||
else {
|
||||
unsigned int ent_no = 0;
|
||||
char zFmt[16]; /* format for all-but-last entries on a line */
|
||||
|
||||
sprintf(zFmt, ENUM_ERR_STR_WIDTH_FMT, (int)max_len);
|
||||
max_len = 78 / max_len; /* max_len is now max entries on a line */
|
||||
fputs(TWO_SPACES_STR, option_usage_fp);
|
||||
|
||||
/*
|
||||
* Loop through all but the last entry
|
||||
*/
|
||||
ct_down = name_ct;
|
||||
while (--ct_down > 0) {
|
||||
if (++ent_no == max_len) {
|
||||
/*
|
||||
* Last entry on a line. Start next line, too.
|
||||
*/
|
||||
fprintf(option_usage_fp, NLSTR_SPACE_FMT, *(paz_names++));
|
||||
ent_no = 0;
|
||||
}
|
||||
|
||||
else
|
||||
fprintf(option_usage_fp, zFmt, *(paz_names++) );
|
||||
}
|
||||
fprintf(option_usage_fp, NLSTR_FMT, *paz_names);
|
||||
}
|
||||
|
||||
if (pOpts > OPTPROC_EMIT_LIMIT) {
|
||||
fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden);
|
||||
|
||||
(*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
|
||||
fprintf(option_usage_fp, zLowerBits, name_ct);
|
||||
fputs(zSetMemberSettings, option_usage_fp);
|
||||
} else {
|
||||
fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a name or number into a binary number.
|
||||
* "~0" and "-1" will be converted to the largest value in the enumeration.
|
||||
*
|
||||
* @param pzName the keyword name (number) to convert
|
||||
* @param pOpts the program's option descriptor
|
||||
* @param pOD the option descriptor for this option
|
||||
* @param paz_names the list of keywords for this option
|
||||
* @param name_ct the count of keywords
|
||||
*/
|
||||
static uintptr_t
|
||||
find_name(char const * pzName, tOptions * pOpts, tOptDesc * pOD,
|
||||
char const * const * paz_names, unsigned int name_ct)
|
||||
{
|
||||
/*
|
||||
* Return the matching index as a pointer sized integer.
|
||||
* The result gets stashed in a char* pointer.
|
||||
*/
|
||||
uintptr_t res = name_ct;
|
||||
size_t len = strlen((char*)pzName);
|
||||
uintptr_t idx;
|
||||
|
||||
if (IS_DEC_DIGIT_CHAR(*pzName)) {
|
||||
char * pz = (char *)(void *)pzName;
|
||||
unsigned long val = strtoul(pz, &pz, 0);
|
||||
if ((*pz == NUL) && (val < name_ct))
|
||||
return (uintptr_t)val;
|
||||
pz_enum_err_fmt = zTooLarge;
|
||||
option_usage_fp = stderr;
|
||||
enum_err(pOpts, pOD, paz_names, (int)name_ct);
|
||||
return name_ct;
|
||||
}
|
||||
|
||||
if (IS_INVERSION_CHAR(*pzName) && (pzName[2] == NUL)) {
|
||||
if ( ((pzName[0] == '~') && (pzName[1] == '0'))
|
||||
|| ((pzName[0] == '-') && (pzName[1] == '1')))
|
||||
return (uintptr_t)(name_ct - 1);
|
||||
goto oops;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for an exact match, but remember any partial matches.
|
||||
* Multiple partial matches means we have an ambiguous match.
|
||||
*/
|
||||
for (idx = 0; idx < name_ct; idx++) {
|
||||
if (strncmp((char*)paz_names[idx], (char*)pzName, len) == 0) {
|
||||
if (paz_names[idx][len] == NUL)
|
||||
return idx; /* full match */
|
||||
|
||||
if (res == name_ct)
|
||||
res = idx; /* save partial match */
|
||||
else
|
||||
res = ~0; /* may yet find full match */
|
||||
}
|
||||
}
|
||||
|
||||
if (res < name_ct)
|
||||
return res; /* partial match */
|
||||
|
||||
oops:
|
||||
|
||||
pz_enum_err_fmt = (res == name_ct) ? zNoKey : zAmbigKey;
|
||||
option_usage_fp = stderr;
|
||||
enum_err(pOpts, pOD, paz_names, (int)name_ct);
|
||||
return name_ct;
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionKeywordName
|
||||
* what: Convert between enumeration values and strings
|
||||
* private:
|
||||
*
|
||||
* arg: tOptDesc*, pOD, enumeration option description
|
||||
* arg: unsigned int, enum_val, the enumeration value to map
|
||||
*
|
||||
* ret_type: char const *
|
||||
* ret_desc: the enumeration name from const memory
|
||||
*
|
||||
* doc: This converts an enumeration value into the matching string.
|
||||
=*/
|
||||
char const *
|
||||
optionKeywordName(tOptDesc * pOD, unsigned int enum_val)
|
||||
{
|
||||
tOptDesc od = {
|
||||
.optArg.argEnum = enum_val };
|
||||
|
||||
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, &od );
|
||||
return od.optArg.argString;
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionEnumerationVal
|
||||
* what: Convert from a string to an enumeration value
|
||||
* private:
|
||||
*
|
||||
* arg: tOptions*, pOpts, the program options descriptor
|
||||
* arg: tOptDesc*, pOD, enumeration option description
|
||||
* arg: char const * const *, paz_names, list of enumeration names
|
||||
* arg: unsigned int, name_ct, number of names in list
|
||||
*
|
||||
* ret_type: uintptr_t
|
||||
* ret_desc: the enumeration value
|
||||
*
|
||||
* doc: This converts the optArg.argString string from the option description
|
||||
* into the index corresponding to an entry in the name list.
|
||||
* This will match the generated enumeration value.
|
||||
* Full matches are always accepted. Partial matches are accepted
|
||||
* if there is only one partial match.
|
||||
=*/
|
||||
uintptr_t
|
||||
optionEnumerationVal(tOptions * pOpts, tOptDesc * pOD,
|
||||
char const * const * paz_names, unsigned int name_ct)
|
||||
{
|
||||
uintptr_t res = 0UL;
|
||||
|
||||
/*
|
||||
* IF the program option descriptor pointer is invalid,
|
||||
* then it is some sort of special request.
|
||||
*/
|
||||
switch ((uintptr_t)pOpts) {
|
||||
case (uintptr_t)OPTPROC_EMIT_USAGE:
|
||||
/*
|
||||
* print the list of enumeration names.
|
||||
*/
|
||||
enum_err(pOpts, pOD, paz_names, (int)name_ct);
|
||||
break;
|
||||
|
||||
case (uintptr_t)OPTPROC_EMIT_SHELL:
|
||||
{
|
||||
unsigned int ix = pOD->optArg.argEnum;
|
||||
/*
|
||||
* print the name string.
|
||||
*/
|
||||
if (ix >= name_ct)
|
||||
printf(INVALID_FMT, ix);
|
||||
else
|
||||
fputs(paz_names[ ix ], stdout);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case (uintptr_t)OPTPROC_RETURN_VALNAME:
|
||||
{
|
||||
unsigned int ix = pOD->optArg.argEnum;
|
||||
/*
|
||||
* Replace the enumeration value with the name string.
|
||||
*/
|
||||
if (ix >= name_ct)
|
||||
return (uintptr_t)INVALID_STR;
|
||||
|
||||
pOD->optArg.argString = paz_names[ix];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
res = find_name(pOD->optArg.argString, pOpts, pOD, paz_names, name_ct);
|
||||
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
pOD->optArg.argString = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
set_memb_usage(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
|
||||
unsigned int name_ct)
|
||||
{
|
||||
/*
|
||||
* print the list of enumeration names.
|
||||
*/
|
||||
(void)pOpts;
|
||||
enum_err(OPTPROC_EMIT_USAGE, pOD, paz_names, (int)name_ct );
|
||||
}
|
||||
|
||||
static void
|
||||
set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
|
||||
unsigned int name_ct)
|
||||
{
|
||||
/*
|
||||
* print the name string.
|
||||
*/
|
||||
unsigned int ix = 0;
|
||||
uintptr_t bits = (uintptr_t)pOD->optCookie;
|
||||
size_t len = 0;
|
||||
|
||||
(void)pOpts;
|
||||
bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
|
||||
|
||||
while (bits != 0) {
|
||||
if (bits & 1) {
|
||||
if (len++ > 0) fputs(OR_STR, stdout);
|
||||
fputs(paz_names[ix], stdout);
|
||||
}
|
||||
if (++ix >= name_ct) break;
|
||||
bits >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_memb_names(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
|
||||
unsigned int name_ct)
|
||||
{
|
||||
char * pz;
|
||||
uintptr_t bits = (uintptr_t)pOD->optCookie;
|
||||
unsigned int ix = 0;
|
||||
size_t len = NONE_STR_LEN + 1;
|
||||
|
||||
(void)pOpts;
|
||||
bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
|
||||
|
||||
/*
|
||||
* Replace the enumeration value with the name string.
|
||||
* First, determine the needed length, then allocate and fill in.
|
||||
*/
|
||||
while (bits != 0) {
|
||||
if (bits & 1)
|
||||
len += strlen(paz_names[ix]) + PLUS_STR_LEN + 1;
|
||||
if (++ix >= name_ct) break;
|
||||
bits >>= 1;
|
||||
}
|
||||
|
||||
pOD->optArg.argString = pz = AGALOC(len, "enum");
|
||||
|
||||
/*
|
||||
* Start by clearing all the bits. We want to turn off any defaults
|
||||
* because we will be restoring to current state, not adding to
|
||||
* the default set of bits.
|
||||
*/
|
||||
memcpy(pz, NONE_STR, NONE_STR_LEN);
|
||||
pz += NONE_STR_LEN;
|
||||
bits = (uintptr_t)pOD->optCookie;
|
||||
bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
|
||||
ix = 0;
|
||||
|
||||
while (bits != 0) {
|
||||
if (bits & 1) {
|
||||
size_t nln = strlen(paz_names[ix]);
|
||||
memcpy(pz, PLUS_STR, PLUS_STR_LEN);
|
||||
memcpy(pz+PLUS_STR_LEN, paz_names[ix], nln);
|
||||
pz += nln + PLUS_STR_LEN;
|
||||
}
|
||||
if (++ix >= name_ct) break;
|
||||
bits >>= 1;
|
||||
}
|
||||
*pz = NUL;
|
||||
}
|
||||
|
||||
/*=export_func optionSetMembers
|
||||
* what: Convert between bit flag values and strings
|
||||
* private:
|
||||
*
|
||||
* arg: tOptions*, pOpts, the program options descriptor
|
||||
* arg: tOptDesc*, pOD, enumeration option description
|
||||
* arg: char const * const *,
|
||||
* paz_names, list of enumeration names
|
||||
* arg: unsigned int, name_ct, number of names in list
|
||||
*
|
||||
* doc: This converts the optArg.argString string from the option description
|
||||
* into the index corresponding to an entry in the name list.
|
||||
* This will match the generated enumeration value.
|
||||
* Full matches are always accepted. Partial matches are accepted
|
||||
* if there is only one partial match.
|
||||
=*/
|
||||
void
|
||||
optionSetMembers(tOptions * pOpts, tOptDesc * pOD,
|
||||
char const* const * paz_names, unsigned int name_ct)
|
||||
{
|
||||
/*
|
||||
* IF the program option descriptor pointer is invalid,
|
||||
* then it is some sort of special request.
|
||||
*/
|
||||
switch ((uintptr_t)pOpts) {
|
||||
case (uintptr_t)OPTPROC_EMIT_USAGE:
|
||||
set_memb_usage(pOpts, pOD, paz_names, name_ct);
|
||||
return;
|
||||
|
||||
case (uintptr_t)OPTPROC_EMIT_SHELL:
|
||||
set_memb_shell(pOpts, pOD, paz_names, name_ct);
|
||||
return;
|
||||
|
||||
case (uintptr_t)OPTPROC_RETURN_VALNAME:
|
||||
set_memb_names(pOpts, pOD, paz_names, name_ct);
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0)
|
||||
return;
|
||||
|
||||
{
|
||||
char const * pzArg = pOD->optArg.argString;
|
||||
uintptr_t res;
|
||||
if ((pzArg == NULL) || (*pzArg == NUL)) {
|
||||
pOD->optCookie = (void*)0;
|
||||
return;
|
||||
}
|
||||
|
||||
res = (uintptr_t)pOD->optCookie;
|
||||
for (;;) {
|
||||
int iv, len;
|
||||
|
||||
pzArg = SPN_SET_SEPARATOR_CHARS(pzArg);
|
||||
iv = (*pzArg == '!');
|
||||
if (iv)
|
||||
pzArg = SPN_WHITESPACE_CHARS(pzArg+1);
|
||||
|
||||
len = BRK_SET_SEPARATOR_CHARS(pzArg) - pzArg;
|
||||
if (len == 0)
|
||||
break;
|
||||
|
||||
if ((len == 3) && (strncmp(pzArg, zAll, 3) == 0)) {
|
||||
if (iv)
|
||||
res = 0;
|
||||
else res = ~0UL;
|
||||
}
|
||||
else if ((len == 4) && (strncmp(pzArg, zNone, 4) == 0)) {
|
||||
if (! iv)
|
||||
res = 0;
|
||||
}
|
||||
else do {
|
||||
char* pz;
|
||||
uintptr_t bit = strtoul(pzArg, &pz, 0);
|
||||
|
||||
if (pz != pzArg + len) {
|
||||
char z[ AO_NAME_SIZE ];
|
||||
char const* p;
|
||||
unsigned int shift_ct;
|
||||
|
||||
if (*pz != NUL) {
|
||||
if (len >= AO_NAME_LIMIT)
|
||||
break;
|
||||
memcpy(z, pzArg, (size_t)len);
|
||||
z[len] = NUL;
|
||||
p = z;
|
||||
} else {
|
||||
p = pzArg;
|
||||
}
|
||||
|
||||
shift_ct = find_name(p, pOpts, pOD, paz_names, name_ct);
|
||||
if (shift_ct >= name_ct) {
|
||||
pOD->optCookie = (void*)0;
|
||||
return;
|
||||
}
|
||||
bit = 1UL << shift_ct;
|
||||
}
|
||||
if (iv)
|
||||
res &= ~bit;
|
||||
else res |= bit;
|
||||
} while (false);
|
||||
|
||||
if (pzArg[len] == NUL)
|
||||
break;
|
||||
pzArg += len + 1;
|
||||
}
|
||||
if (name_ct < (8 * sizeof(uintptr_t))) {
|
||||
res &= (1UL << name_ct) - 1UL;
|
||||
}
|
||||
|
||||
pOD->optCookie = (void*)res;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/enumeration.c */
|
||||
+262
@@ -0,0 +1,262 @@
|
||||
|
||||
/**
|
||||
* \file environment.c
|
||||
*
|
||||
* Time-stamp: "2012-04-01 05:59:15 bkorb"
|
||||
*
|
||||
* This file contains all of the routines that must be linked into
|
||||
* an executable to use the generated option processing. The optional
|
||||
* routines are in separately compiled modules so that they will not
|
||||
* necessarily be linked in.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static void
|
||||
do_env_opt(tOptState * os, char * env_name,
|
||||
tOptions * pOpts, teEnvPresetType type);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/*
|
||||
* doPrognameEnv - check for preset values from the ${PROGNAME}
|
||||
* environment variable. This is accomplished by parsing the text into
|
||||
* tokens, temporarily replacing the arg vector and calling
|
||||
* immediate_opts and/or regular_opts.
|
||||
*/
|
||||
LOCAL void
|
||||
doPrognameEnv(tOptions * pOpts, teEnvPresetType type)
|
||||
{
|
||||
char const * pczOptStr = getenv(pOpts->pzPROGNAME);
|
||||
token_list_t* pTL;
|
||||
int sv_argc;
|
||||
tAoUI sv_flag;
|
||||
char ** sv_argv;
|
||||
|
||||
/*
|
||||
* No such beast? Then bail now.
|
||||
*/
|
||||
if (pczOptStr == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Tokenize the string. If there's nothing of interest, we'll bail
|
||||
* here immediately.
|
||||
*/
|
||||
pTL = ao_string_tokenize(pczOptStr);
|
||||
if (pTL == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Substitute our $PROGNAME argument list for the real one
|
||||
*/
|
||||
sv_argc = pOpts->origArgCt;
|
||||
sv_argv = pOpts->origArgVect;
|
||||
sv_flag = pOpts->fOptSet;
|
||||
|
||||
/*
|
||||
* We add a bogus pointer to the start of the list. The program name
|
||||
* has already been pulled from "argv", so it won't get dereferenced.
|
||||
* The option scanning code will skip the "program name" at the start
|
||||
* of this list of tokens, so we accommodate this way ....
|
||||
*/
|
||||
{
|
||||
uintptr_t v = (uintptr_t)(pTL->tkn_list);
|
||||
pOpts->origArgVect = (void *)(v - sizeof(char *));
|
||||
}
|
||||
pOpts->origArgCt = pTL->tkn_ct + 1;
|
||||
pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
|
||||
|
||||
pOpts->curOptIdx = 1;
|
||||
pOpts->pzCurOpt = NULL;
|
||||
|
||||
switch (type) {
|
||||
case ENV_IMM:
|
||||
(void)immediate_opts(pOpts);
|
||||
break;
|
||||
|
||||
case ENV_ALL:
|
||||
(void)immediate_opts(pOpts);
|
||||
pOpts->curOptIdx = 1;
|
||||
pOpts->pzCurOpt = NULL;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case ENV_NON_IMM:
|
||||
(void)regular_opts(pOpts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up the temporary arg vector and restore the original program args.
|
||||
*/
|
||||
free(pTL);
|
||||
pOpts->origArgVect = sv_argv;
|
||||
pOpts->origArgCt = sv_argc;
|
||||
pOpts->fOptSet = sv_flag;
|
||||
}
|
||||
|
||||
static void
|
||||
do_env_opt(tOptState * os, char * env_name,
|
||||
tOptions * pOpts, teEnvPresetType type)
|
||||
{
|
||||
os->pzOptArg = getenv(env_name);
|
||||
if (os->pzOptArg == NULL)
|
||||
return;
|
||||
|
||||
os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState;
|
||||
os->optType = TOPT_UNDEFINED;
|
||||
|
||||
if ( (os->pOD->pz_DisablePfx != NULL)
|
||||
&& (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) {
|
||||
os->flags |= OPTST_DISABLED;
|
||||
os->pzOptArg = NULL;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ENV_IMM:
|
||||
/*
|
||||
* Process only immediate actions
|
||||
*/
|
||||
if (DO_IMMEDIATELY(os->flags))
|
||||
break;
|
||||
return;
|
||||
|
||||
case ENV_NON_IMM:
|
||||
/*
|
||||
* Process only NON immediate actions
|
||||
*/
|
||||
if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags))
|
||||
break;
|
||||
return;
|
||||
|
||||
default: /* process everything */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the option value string is persistent and consistent.
|
||||
*
|
||||
* The interpretation of the option value depends
|
||||
* on the type of value argument the option takes
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
|
||||
/*
|
||||
* Ignore any value.
|
||||
*/
|
||||
os->pzOptArg = NULL;
|
||||
|
||||
} else if (os->pzOptArg[0] == NUL) {
|
||||
/*
|
||||
* If the argument is the empty string and the argument is
|
||||
* optional, then treat it as if the option was not specified.
|
||||
*/
|
||||
if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0)
|
||||
return;
|
||||
os->pzOptArg = NULL;
|
||||
|
||||
} else {
|
||||
AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument");
|
||||
os->flags |= OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
handle_opt(pOpts, os);
|
||||
}
|
||||
|
||||
/*
|
||||
* env_presets - check for preset values from the envrionment
|
||||
* This routine should process in all, immediate or normal modes....
|
||||
*/
|
||||
LOCAL void
|
||||
env_presets(tOptions * pOpts, teEnvPresetType type)
|
||||
{
|
||||
int ct;
|
||||
tOptState st;
|
||||
char* pzFlagName;
|
||||
size_t spaceLeft;
|
||||
char zEnvName[ AO_NAME_SIZE ];
|
||||
|
||||
/*
|
||||
* Finally, see if we are to look at the environment
|
||||
* variables for initial values.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0)
|
||||
return;
|
||||
|
||||
doPrognameEnv(pOpts, type);
|
||||
|
||||
ct = pOpts->presetOptCt;
|
||||
st.pOD = pOpts->pOptDesc;
|
||||
|
||||
pzFlagName = zEnvName
|
||||
+ snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME);
|
||||
spaceLeft = AO_NAME_SIZE - (pzFlagName - zEnvName) - 1;
|
||||
|
||||
for (;ct-- > 0; st.pOD++) {
|
||||
size_t nln;
|
||||
|
||||
/*
|
||||
* If presetting is disallowed, then skip this entry
|
||||
*/
|
||||
if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0)
|
||||
|| (st.pOD->optEquivIndex != NO_EQUIVALENT) )
|
||||
continue;
|
||||
|
||||
/*
|
||||
* IF there is no such environment variable,
|
||||
* THEN skip this entry, too.
|
||||
*/
|
||||
nln = strlen(st.pOD->pz_NAME) + 1;
|
||||
if (nln <= spaceLeft) {
|
||||
/*
|
||||
* Set up the option state
|
||||
*/
|
||||
memcpy(pzFlagName, st.pOD->pz_NAME, nln);
|
||||
do_env_opt(&st, zEnvName, pOpts, type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special handling for ${PROGNAME_LOAD_OPTS}
|
||||
*/
|
||||
if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
|
||||
&& (pOpts->specOptIdx.save_opts != 0)) {
|
||||
size_t nln;
|
||||
st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
|
||||
|
||||
if (st.pOD->pz_NAME == NULL)
|
||||
return;
|
||||
|
||||
nln = strlen(st.pOD->pz_NAME) + 1;
|
||||
|
||||
if (nln > spaceLeft)
|
||||
return;
|
||||
|
||||
memcpy(pzFlagName, st.pOD->pz_NAME, nln);
|
||||
do_env_opt(&st, zEnvName, pOpts, type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/environment.c */
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
|
||||
/**
|
||||
* \file file.c
|
||||
*
|
||||
* Time-stamp: "2011-08-06 08:49:35 bkorb"
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make sure the directory containing the subject file exists and that
|
||||
* the file exists or does not exist, per the option requirements.
|
||||
*
|
||||
* @param ftype file existence type flags
|
||||
* @param pOpts program option descriptor
|
||||
* @param pOD the option descriptor
|
||||
*/
|
||||
static void
|
||||
check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
char const * fname = pOD->optArg.argString;
|
||||
struct stat sb;
|
||||
|
||||
errno = 0;
|
||||
|
||||
switch (ftype & FTYPE_MODE_EXIST_MASK) {
|
||||
case FTYPE_MODE_MUST_NOT_EXIST:
|
||||
if ((stat(fname, &sb) == 0) || (errno != ENOENT)) {
|
||||
if (errno == 0)
|
||||
errno = EINVAL;
|
||||
fprintf(stderr, zFSOptError, errno, strerror(errno),
|
||||
zFSOptErrNoExist, fname, pOD->pz_Name);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
case FTYPE_MODE_MAY_EXIST:
|
||||
{
|
||||
char * p = strrchr(fname, DIRCH);
|
||||
size_t l;
|
||||
|
||||
if (p == NULL)
|
||||
/*
|
||||
* The file may or may not exist and its directory is ".".
|
||||
* Assume that "." exists.
|
||||
*/
|
||||
break;
|
||||
|
||||
l = p - fname;
|
||||
p = AGALOC(l + 1, "fname");
|
||||
memcpy(p, fname, l);
|
||||
p[l] = NUL;
|
||||
|
||||
if ((stat(p, &sb) != 0) || (errno = EINVAL, ! S_ISDIR(sb.st_mode))) {
|
||||
fprintf(stderr, zFSOptError, errno, strerror(errno),
|
||||
zFSOptErrMayExist, fname, pOD->pz_Name);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
AGFREE(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case FTYPE_MODE_MUST_EXIST:
|
||||
if ( (stat(fname, &sb) != 0)
|
||||
|| (errno = EINVAL, ! S_ISREG(sb.st_mode)) ) {
|
||||
fprintf(stderr, zFSOptError, errno, strerror(errno),
|
||||
zFSOptErrMustExist, fname,
|
||||
pOD->pz_Name);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the specified file with open(2) and save the FD.
|
||||
*
|
||||
* @param pOpts program option descriptor
|
||||
* @param pOD the option descriptor
|
||||
* @param mode the open mode (uses int flags value)
|
||||
*/
|
||||
static void
|
||||
open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode)
|
||||
{
|
||||
int fd = open(pOD->optArg.argString, mode.file_flags);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, zFSOptError, errno, strerror(errno),
|
||||
zFSOptErrOpen, pOD->optArg.argString, pOD->pz_Name);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
|
||||
pOD->optCookie = (void *)pOD->optArg.argString;
|
||||
else
|
||||
AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name");
|
||||
|
||||
pOD->optArg.argFd = fd;
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the specified file with open(2) and save the FD.
|
||||
*
|
||||
* @param pOpts program option descriptor
|
||||
* @param pOD the option descriptor
|
||||
* @param mode the open mode (uses "char *" mode value)
|
||||
*/
|
||||
static void
|
||||
fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode)
|
||||
{
|
||||
FILE* fp = fopen(pOD->optArg.argString, mode.file_mode);
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, zFSOptError, errno, strerror(errno),
|
||||
zFSOptErrFopen, pOD->optArg.argString, pOD->pz_Name);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
|
||||
pOD->optCookie = (void *)pOD->optArg.argString;
|
||||
else
|
||||
AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name");
|
||||
|
||||
pOD->optArg.argFp = fp;
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
/*=export_func optionFileCheck
|
||||
* private:
|
||||
*
|
||||
* what: Decipher a boolean value
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
* arg: + teOptFileType + ftype + File handling type +
|
||||
* arg: + tuFileMode + mode + file open mode (if needed) +
|
||||
*
|
||||
* doc:
|
||||
* Make sure the named file conforms with the file type mode.
|
||||
* The mode specifies if the file must exist, must not exist or may
|
||||
* (or may not) exist. The mode may also specify opening the
|
||||
* file: don't, open just the descriptor (fd), or open as a stream
|
||||
* (FILE* pointer).
|
||||
=*/
|
||||
void
|
||||
optionFileCheck(tOptions * pOpts, tOptDesc * pOD,
|
||||
teOptFileType ftype, tuFileMode mode)
|
||||
{
|
||||
if (pOpts <= OPTPROC_EMIT_LIMIT) {
|
||||
if (pOpts != OPTPROC_EMIT_USAGE)
|
||||
return;
|
||||
|
||||
switch (ftype & FTYPE_MODE_EXIST_MASK) {
|
||||
case FTYPE_MODE_MUST_NOT_EXIST:
|
||||
fputs(zFileCannotExist, option_usage_fp);
|
||||
break;
|
||||
|
||||
case FTYPE_MODE_MUST_EXIST:
|
||||
fputs(zFileMustExist, option_usage_fp);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0) {
|
||||
if (pOD->optCookie != NULL)
|
||||
AGFREE(pOD->optCookie);
|
||||
return;
|
||||
}
|
||||
|
||||
check_existence(ftype, pOpts, pOD);
|
||||
|
||||
switch (ftype & FTYPE_MODE_OPEN_MASK) {
|
||||
default:
|
||||
case FTYPE_MODE_NO_OPEN: break;
|
||||
case FTYPE_MODE_OPEN_FD: open_file_fd( pOpts, pOD, mode); break;
|
||||
case FTYPE_MODE_FOPEN_FP: fopen_file_fp(pOpts, pOD, mode); break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/file.c */
|
||||
+566
@@ -0,0 +1,566 @@
|
||||
/**
|
||||
* @file check.c
|
||||
*
|
||||
* @brief Hunt for options in the option descriptor list
|
||||
*
|
||||
* Time-stamp: "2012-01-29 19:07:30 bkorb"
|
||||
*
|
||||
* This file contains the routines that deal with processing quoted strings
|
||||
* into an internal format.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/**
|
||||
* find the name and name length we are looking for
|
||||
*/
|
||||
static int
|
||||
parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz)
|
||||
{
|
||||
int res = 0;
|
||||
char const * p = *nm_pp;
|
||||
*arg_pp = NULL;
|
||||
|
||||
for (;;) {
|
||||
switch (*(p++)) {
|
||||
case NUL: return res;
|
||||
|
||||
case '=':
|
||||
if (res >= (int)bufsz)
|
||||
return -1;
|
||||
|
||||
memcpy(buf, *nm_pp, res);
|
||||
|
||||
buf[res] = NUL;
|
||||
*nm_pp = buf;
|
||||
*arg_pp = (char *)p;
|
||||
return res;
|
||||
|
||||
default:
|
||||
res++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* print out the options that match the given name.
|
||||
*
|
||||
* @param pOpts option data
|
||||
* @param opt_name name of option to look for
|
||||
*/
|
||||
static void
|
||||
opt_ambiguities(tOptions * opts, char const * name, int nm_len)
|
||||
{
|
||||
char const * const hyph =
|
||||
NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER;
|
||||
|
||||
tOptDesc * pOD = opts->pOptDesc;
|
||||
int idx = 0;
|
||||
|
||||
fputs(zAmbigList, stderr);
|
||||
do {
|
||||
if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0)
|
||||
fprintf(stderr, zAmbiguous, hyph, pOD->pz_Name);
|
||||
|
||||
else if ( (pOD->pz_DisableName != NULL)
|
||||
&& (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
|
||||
)
|
||||
fprintf(stderr, zAmbiguous, hyph, pOD->pz_DisableName);
|
||||
} while (pOD++, (++idx < opts->optCt));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the number of options that match the name
|
||||
*
|
||||
* @param pOpts option data
|
||||
* @param opt_name name of option to look for
|
||||
* @param nm_len length of provided name
|
||||
* @param index pointer to int for option index
|
||||
* @param disable pointer to bool to mark disabled option
|
||||
* @return count of options that match
|
||||
*/
|
||||
static int
|
||||
opt_match_ct(tOptions * opts, char const * name, int nm_len,
|
||||
int * ixp, bool * disable)
|
||||
{
|
||||
int matchCt = 0;
|
||||
int idx = 0;
|
||||
int idxLim = opts->optCt;
|
||||
tOptDesc * pOD = opts->pOptDesc;
|
||||
|
||||
do {
|
||||
/*
|
||||
* If option disabled or a doc option, skip to next
|
||||
*/
|
||||
if (pOD->pz_Name == NULL)
|
||||
continue;
|
||||
|
||||
if ( SKIP_OPT(pOD)
|
||||
&& (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT)))
|
||||
continue;
|
||||
|
||||
if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) {
|
||||
/*
|
||||
* IF we have a complete match
|
||||
* THEN it takes priority over any already located partial
|
||||
*/
|
||||
if (pOD->pz_Name[ nm_len ] == NUL) {
|
||||
*ixp = idx;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IF there is a disable name
|
||||
* *AND* the option name matches the disable name
|
||||
* THEN ...
|
||||
*/
|
||||
else if ( (pOD->pz_DisableName != NULL)
|
||||
&& (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
|
||||
) {
|
||||
*disable = true;
|
||||
|
||||
/*
|
||||
* IF we have a complete match
|
||||
* THEN it takes priority over any already located partial
|
||||
*/
|
||||
if (pOD->pz_DisableName[ nm_len ] == NUL) {
|
||||
*ixp = idx;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
continue; /* does not match any option */
|
||||
|
||||
/*
|
||||
* We found a full or partial match, either regular or disabling.
|
||||
* Remember the index for later.
|
||||
*/
|
||||
*ixp = idx;
|
||||
++matchCt;
|
||||
|
||||
} while (pOD++, (++idx < idxLim));
|
||||
|
||||
return matchCt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the option to the indicated option number.
|
||||
*
|
||||
* @param opts option data
|
||||
* @param arg option argument (if glued to name)
|
||||
* @param idx option index
|
||||
* @param disable mark disabled option
|
||||
* @param st state about current option
|
||||
*/
|
||||
static tSuccess
|
||||
opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st)
|
||||
{
|
||||
tOptDesc * pOD = opts->pOptDesc + idx;
|
||||
|
||||
if (SKIP_OPT(pOD)) {
|
||||
if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0)
|
||||
return FAILURE;
|
||||
|
||||
fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name);
|
||||
if (pOD->pzText != NULL)
|
||||
fprintf(stderr, SET_OFF_FMT, pOD->pzText);
|
||||
fputc(NL, stderr);
|
||||
(*opts->pUsageProc)(opts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE); /* to be certain */
|
||||
}
|
||||
|
||||
/*
|
||||
* IF we found a disablement name,
|
||||
* THEN set the bit in the callers' flag word
|
||||
*/
|
||||
if (disable)
|
||||
st->flags |= OPTST_DISABLED;
|
||||
|
||||
st->pOD = pOD;
|
||||
st->pzOptArg = arg;
|
||||
st->optType = TOPT_LONG;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* An option was not found. Check for default option and set it
|
||||
* if there is one. Otherwise, handle the error.
|
||||
*
|
||||
* @param opts option data
|
||||
* @param name name of option to look for
|
||||
* @param arg option argument
|
||||
* @param st state about current option
|
||||
*
|
||||
* @return success status
|
||||
*/
|
||||
static tSuccess
|
||||
opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st)
|
||||
{
|
||||
/*
|
||||
* IF there is no equal sign
|
||||
* *AND* we are using named arguments
|
||||
* *AND* there is a default named option,
|
||||
* THEN return that option.
|
||||
*/
|
||||
if ( (arg == NULL)
|
||||
&& NAMED_OPTS(opts)
|
||||
&& (opts->specOptIdx.default_opt != NO_EQUIVALENT)) {
|
||||
|
||||
st->pOD = opts->pOptDesc + opts->specOptIdx.default_opt;
|
||||
st->pzOptArg = name;
|
||||
st->optType = TOPT_DEFAULT;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
fprintf(stderr, zIllOptStr, opts->pzProgPath, name);
|
||||
(*opts->pUsageProc)(opts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE); /* to be certain */
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Several options match the provided name.
|
||||
*
|
||||
* @param opts option data
|
||||
* @param name name of option to look for
|
||||
* @param match_ct number of matching options
|
||||
*
|
||||
* @return success status (always FAILURE, if it returns)
|
||||
*/
|
||||
static tSuccess
|
||||
opt_ambiguous(tOptions * opts, char const * name, int match_ct)
|
||||
{
|
||||
if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
fprintf(stderr, zAmbigOptStr, opts->pzProgPath, name, match_ct);
|
||||
if (match_ct <= 4)
|
||||
opt_ambiguities(opts, name, strlen(name));
|
||||
(*opts->pUsageProc)(opts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE); /* to be certain */
|
||||
}
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/*=export_func optionVendorOption
|
||||
* private:
|
||||
*
|
||||
* what: Process a vendor option
|
||||
* arg: + tOptions * + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc * + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* For POSIX specified utilities, the options are constrained to the options,
|
||||
* @xref{config attributes, Program Configuration}. AutoOpts clients should
|
||||
* never specify this directly. It gets referenced when the option
|
||||
* definitions contain a "vendor-opt" attribute.
|
||||
=*/
|
||||
void
|
||||
optionVendorOption(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
tOptState opt_st = OPTSTATE_INITIALIZER(PRESET);
|
||||
char const * vopt_str = pOD->optArg.argString;
|
||||
|
||||
if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0)
|
||||
opt_st.flags = OPTST_DEFINED;
|
||||
|
||||
if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0)
|
||||
|| ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st))
|
||||
|| ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) )
|
||||
{
|
||||
fprintf(stderr, zIllVendOptStr, vopt_str);
|
||||
(*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we are in immediate handling state.
|
||||
*/
|
||||
if (pOpts->fOptSet & OPTPROC_IMMEDIATE) {
|
||||
/*
|
||||
* See if the enclosed option is okay with that state.
|
||||
*/
|
||||
if (DO_IMMEDIATELY(opt_st.flags))
|
||||
(void)handle_opt(pOpts, &opt_st);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* non-immediate direction.
|
||||
* See if the enclosed option is okay with that state.
|
||||
*/
|
||||
if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags))
|
||||
(void)handle_opt(pOpts, &opt_st);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the option descriptor by full name.
|
||||
*
|
||||
* @param pOpts option data
|
||||
* @param opt_name name of option to look for
|
||||
* @param pOptState state about current option
|
||||
*
|
||||
* @return success status
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
opt_find_long(tOptions * pOpts, char const * opt_name, tOptState * pOptState)
|
||||
{
|
||||
char name_buf[128];
|
||||
char * opt_arg;
|
||||
int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf));
|
||||
|
||||
int matchIdx = 0;
|
||||
bool disable = false;
|
||||
int match_ct =
|
||||
opt_match_ct(pOpts, opt_name, nm_len, &matchIdx, &disable);
|
||||
|
||||
/*
|
||||
* See if we found one match, no matches or multiple matches.
|
||||
*/
|
||||
switch (match_ct) {
|
||||
case 1: return opt_set(pOpts, opt_arg, matchIdx, disable, pOptState);
|
||||
case 0: return opt_unknown(pOpts, opt_name, opt_arg, pOptState);
|
||||
default: return opt_ambiguous(pOpts, opt_name, match_ct);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the short option descriptor for the current option
|
||||
*
|
||||
* @param pOpts option data
|
||||
* @param optValue option flag character
|
||||
* @param pOptState state about current option
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
opt_find_short(tOptions* pOpts, uint_t optValue, tOptState* pOptState)
|
||||
{
|
||||
tOptDesc* pRes = pOpts->pOptDesc;
|
||||
int ct = pOpts->optCt;
|
||||
|
||||
/*
|
||||
* Search the option list
|
||||
*/
|
||||
do {
|
||||
if (optValue != pRes->optValue)
|
||||
continue;
|
||||
|
||||
if (SKIP_OPT(pRes)) {
|
||||
if ( (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
|
||||
&& (pRes->pz_Name != NULL)) {
|
||||
fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name);
|
||||
if (pRes->pzText != NULL)
|
||||
fprintf(stderr, SET_OFF_FMT, pRes->pzText);
|
||||
fputc(NL, stderr);
|
||||
(*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE); /* to be certain */
|
||||
}
|
||||
goto short_opt_error;
|
||||
}
|
||||
|
||||
pOptState->pOD = pRes;
|
||||
pOptState->optType = TOPT_SHORT;
|
||||
return SUCCESS;
|
||||
|
||||
} while (pRes++, --ct > 0);
|
||||
|
||||
/*
|
||||
* IF the character value is a digit
|
||||
* AND there is a special number option ("-n")
|
||||
* THEN the result is the "option" itself and the
|
||||
* option is the specially marked "number" option.
|
||||
*/
|
||||
if ( IS_DEC_DIGIT_CHAR(optValue)
|
||||
&& (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) {
|
||||
pOptState->pOD = \
|
||||
pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option;
|
||||
(pOpts->pzCurOpt)--;
|
||||
pOptState->optType = TOPT_SHORT;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
short_opt_error:
|
||||
|
||||
/*
|
||||
* IF we are to stop on errors (the default, actually)
|
||||
* THEN call the usage procedure.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
|
||||
fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue);
|
||||
(*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE); /* to be certain */
|
||||
}
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
LOCAL tSuccess
|
||||
get_opt_arg(tOptions * pOpts, tOptState * pOptState)
|
||||
{
|
||||
pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK);
|
||||
|
||||
/*
|
||||
* Figure out what to do about option arguments. An argument may be
|
||||
* required, not associated with the option, or be optional. We detect the
|
||||
* latter by examining for an option marker on the next possible argument.
|
||||
* Disabled mode option selection also disables option arguments.
|
||||
*/
|
||||
{
|
||||
enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE;
|
||||
tSuccess res;
|
||||
|
||||
if ((pOptState->flags & OPTST_DISABLED) != 0)
|
||||
arg_type = ARG_NONE;
|
||||
|
||||
else if (OPTST_GET_ARGTYPE(pOptState->flags) == OPARG_TYPE_NONE)
|
||||
arg_type = ARG_NONE;
|
||||
|
||||
else if (pOptState->flags & OPTST_ARG_OPTIONAL)
|
||||
arg_type = ARG_MAY;
|
||||
|
||||
else
|
||||
arg_type = ARG_MUST;
|
||||
|
||||
switch (arg_type) {
|
||||
case ARG_MUST: res = next_opt_arg_must(pOpts, pOptState); break;
|
||||
case ARG_MAY: res = next_opt_arg_may( pOpts, pOptState); break;
|
||||
case ARG_NONE: res = next_opt_arg_none(pOpts, pOptState); break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the option descriptor for the current option
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
find_opt(tOptions * pOpts, tOptState * pOptState)
|
||||
{
|
||||
/*
|
||||
* IF we are continuing a short option list (e.g. -xyz...)
|
||||
* THEN continue a single flag option.
|
||||
* OTHERWISE see if there is room to advance and then do so.
|
||||
*/
|
||||
if ((pOpts->pzCurOpt != NULL) && (*pOpts->pzCurOpt != NUL))
|
||||
return opt_find_short(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState);
|
||||
|
||||
if (pOpts->curOptIdx >= pOpts->origArgCt)
|
||||
return PROBLEM; /* NORMAL COMPLETION */
|
||||
|
||||
pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx ];
|
||||
|
||||
/*
|
||||
* IF all arguments must be named options, ...
|
||||
*/
|
||||
if (NAMED_OPTS(pOpts)) {
|
||||
char * pz = pOpts->pzCurOpt;
|
||||
int def;
|
||||
tSuccess res;
|
||||
tAoUS * def_opt;
|
||||
|
||||
pOpts->curOptIdx++;
|
||||
|
||||
if (*pz != '-')
|
||||
return opt_find_long(pOpts, pz, pOptState);
|
||||
|
||||
/*
|
||||
* The name is prefixed with one or more hyphens. Strip them off
|
||||
* and disable the "default_opt" setting. Use heavy recasting to
|
||||
* strip off the "const" quality of the "default_opt" field.
|
||||
*/
|
||||
while (*(++pz) == '-') ;
|
||||
def_opt = (void *)&(pOpts->specOptIdx.default_opt);
|
||||
def = *def_opt;
|
||||
*def_opt = NO_EQUIVALENT;
|
||||
res = opt_find_long(pOpts, pz, pOptState);
|
||||
*def_opt = def;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note the kind of flag/option marker
|
||||
*/
|
||||
if (*((pOpts->pzCurOpt)++) != '-')
|
||||
return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
|
||||
|
||||
/*
|
||||
* Special hack for a hyphen by itself
|
||||
*/
|
||||
if (*(pOpts->pzCurOpt) == NUL)
|
||||
return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
|
||||
|
||||
/*
|
||||
* The current argument is to be processed as an option argument
|
||||
*/
|
||||
pOpts->curOptIdx++;
|
||||
|
||||
/*
|
||||
* We have an option marker.
|
||||
* Test the next character for long option indication
|
||||
*/
|
||||
if (pOpts->pzCurOpt[0] == '-') {
|
||||
if (*++(pOpts->pzCurOpt) == NUL)
|
||||
/*
|
||||
* NORMAL COMPLETION - NOT this arg, but rest are operands
|
||||
*/
|
||||
return PROBLEM;
|
||||
|
||||
/*
|
||||
* We do not allow the hyphen to be used as a flag value.
|
||||
* Therefore, if long options are not to be accepted, we punt.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_LONGOPT) == 0) {
|
||||
fprintf(stderr, zIllOptStr, pOpts->pzProgPath,
|
||||
pOpts->pzCurOpt-2);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return opt_find_long(pOpts, pOpts->pzCurOpt, pOptState);
|
||||
}
|
||||
|
||||
/*
|
||||
* If short options are not allowed, then do long
|
||||
* option processing. Otherwise the character must be a
|
||||
* short (i.e. single character) option.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_SHORTOPT) != 0)
|
||||
return opt_find_short(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState);
|
||||
|
||||
return opt_find_long(pOpts, pOpts->pzCurOpt, pOptState);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/find.c */
|
||||
@@ -0,0 +1,452 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (genshell.c)
|
||||
*
|
||||
* It has been AutoGen-ed May 6, 2012 at 04:20:59 PM by AutoGen 5.16pre36
|
||||
* From the definitions genshell.def
|
||||
* and the template file options
|
||||
*
|
||||
* Generated from AutoOpts 36:4:11 templates.
|
||||
*
|
||||
* AutoOpts is a copyrighted work. This source file is not encumbered
|
||||
* by AutoOpts licensing, but is provided under the licensing terms chosen
|
||||
* by the genshellopt author or copyright holder. AutoOpts is
|
||||
* licensed under the terms of the LGPL. The redistributable library
|
||||
* (``libopts'') is licensed under the terms of either the LGPL or, at the
|
||||
* users discretion, the BSD license. See the AutoOpts and/or libopts sources
|
||||
* for details.
|
||||
*
|
||||
* The genshellopt program is copyrighted and licensed
|
||||
* under the following terms:
|
||||
*
|
||||
* Copyright (C) 1999-2012 Bruce Korb, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* GNU General Public License, version 3 or later
|
||||
* <http://gnu.org/licenses/gpl.html>
|
||||
*
|
||||
* genshellopt is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* genshellopt is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __doxygen__
|
||||
#define OPTION_CODE_COMPILE 1
|
||||
#include "genshell.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern FILE * option_usage_fp;
|
||||
|
||||
/* TRANSLATORS: choose the translation for option names wisely because you
|
||||
cannot ever change your mind. */
|
||||
#define zCopyright (genshellopt_opt_strs+0)
|
||||
#define zLicenseDescrip (genshellopt_opt_strs+260)
|
||||
|
||||
extern tUsageProc genshelloptUsage;
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* genshellopt option static const strings
|
||||
*/
|
||||
static char const genshellopt_opt_strs[1690] =
|
||||
/* 0 */ "genshellopt 1\n"
|
||||
"Copyright (C) 1999-2012 Bruce Korb, all rights reserved.\n"
|
||||
"This is free software. It is licensed for use, modification and\n"
|
||||
"redistribution under the terms of the\n"
|
||||
"GNU General Public License, version 3 or later\n"
|
||||
" <http://gnu.org/licenses/gpl.html>\n\0"
|
||||
/* 260 */ "genshellopt is free software: you can redistribute it and/or modify it\n"
|
||||
"under the terms of the GNU General Public License as published by the Free\n"
|
||||
"Software Foundation, either version 3 of the License, or (at your option)\n"
|
||||
"any later version.\n\n"
|
||||
"genshellopt is distributed in the hope that it will be useful, but WITHOUT\n"
|
||||
"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n"
|
||||
"FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n"
|
||||
"more details.\n\n"
|
||||
"You should have received a copy of the GNU General Public License along\n"
|
||||
"with this program. If not, see <http://www.gnu.org/licenses/>.\n\0"
|
||||
/* 871 */ "Output Script File\0"
|
||||
/* 890 */ "SCRIPT\0"
|
||||
/* 897 */ "script\0"
|
||||
/* 904 */ "Shell name (follows \"#!\" magic)\0"
|
||||
/* 936 */ "SHELL\0"
|
||||
/* 942 */ "no-shell\0"
|
||||
/* 951 */ "no\0"
|
||||
/* 954 */ "Display extended usage information and exit\0"
|
||||
/* 998 */ "help\0"
|
||||
/* 1003 */ "Extended usage information passed thru pager\0"
|
||||
/* 1048 */ "more-help\0"
|
||||
/* 1058 */ "Output version information and exit\0"
|
||||
/* 1094 */ "version\0"
|
||||
/* 1102 */ "GENSHELLOPT\0"
|
||||
/* 1114 */ "genshellopt - Generate Shell Option Processing Script - Ver. 1\n"
|
||||
"USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
|
||||
/* 1235 */ "autogen-users@lists.sourceforge.net\0"
|
||||
/* 1271 */ "\n"
|
||||
"Note that ``shell'' is only useful if the output file does not already\n"
|
||||
"exist. If it does, then the shell name and optional first argument will be\n"
|
||||
"extracted from the script file.\n\0"
|
||||
/* 1452 */ "\n"
|
||||
"If the script file already exists and contains Automated Option Processing\n"
|
||||
"text, the second line of the file through the ending tag will be replaced\n"
|
||||
"by the newly generated text. The first ``#!'' line will be regenerated.\n\0"
|
||||
/* 1676 */ "genshellopt 1";
|
||||
|
||||
/*
|
||||
* script option description:
|
||||
*/
|
||||
#define SCRIPT_DESC (genshellopt_opt_strs+871)
|
||||
#define SCRIPT_NAME (genshellopt_opt_strs+890)
|
||||
#define SCRIPT_name (genshellopt_opt_strs+897)
|
||||
#define SCRIPT_FLAGS (OPTST_DISABLED \
|
||||
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
|
||||
|
||||
/*
|
||||
* shell option description:
|
||||
*/
|
||||
#define SHELL_DESC (genshellopt_opt_strs+904)
|
||||
#define SHELL_NAME (genshellopt_opt_strs+936)
|
||||
#define NOT_SHELL_name (genshellopt_opt_strs+942)
|
||||
#define NOT_SHELL_PFX (genshellopt_opt_strs+951)
|
||||
#define SHELL_name (NOT_SHELL_name + 3)
|
||||
#define SHELL_FLAGS (OPTST_INITENABLED \
|
||||
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
|
||||
|
||||
/*
|
||||
* Help/More_Help/Version option descriptions:
|
||||
*/
|
||||
#define HELP_DESC (genshellopt_opt_strs+954)
|
||||
#define HELP_name (genshellopt_opt_strs+998)
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
#define MORE_HELP_DESC (genshellopt_opt_strs+1003)
|
||||
#define MORE_HELP_name (genshellopt_opt_strs+1048)
|
||||
#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
|
||||
#else
|
||||
#define MORE_HELP_DESC NULL
|
||||
#define MORE_HELP_name NULL
|
||||
#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
|
||||
#endif
|
||||
#ifdef NO_OPTIONAL_OPT_ARGS
|
||||
# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT)
|
||||
#else
|
||||
# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
|
||||
OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT)
|
||||
#endif
|
||||
#define VER_DESC (genshellopt_opt_strs+1058)
|
||||
#define VER_name (genshellopt_opt_strs+1094)
|
||||
/*
|
||||
* Declare option callback procedures
|
||||
*/
|
||||
extern tOptProc
|
||||
optionBooleanVal, optionNestedVal, optionNumericVal,
|
||||
optionPagedUsage, optionPrintVersion, optionResetOpt,
|
||||
optionStackArg, optionTimeDate, optionTimeVal,
|
||||
optionUnstackArg, optionVendorOption;
|
||||
static tOptProc
|
||||
doUsageOpt;
|
||||
#define VER_PROC optionPrintVersion
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/**
|
||||
* Define the genshellopt Option Descriptions.
|
||||
* This is an array of GENSHELL_OPTION_CT entries, one for each
|
||||
* option that the genshellopt program responds to.
|
||||
*/
|
||||
static tOptDesc optDesc[GENSHELL_OPTION_CT] = {
|
||||
{ /* entry idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT,
|
||||
/* equiv idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ SCRIPT_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL }, /* --script */
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ NULL,
|
||||
/* desc, NAME, name */ SCRIPT_DESC, SCRIPT_NAME, SCRIPT_name,
|
||||
/* disablement strs */ NULL, NULL },
|
||||
|
||||
{ /* entry idx, value */ 1, VALUE_GENSHELL_OPT_SHELL,
|
||||
/* equiv idx, value */ 1, VALUE_GENSHELL_OPT_SHELL,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ SHELL_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL }, /* --shell */
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ NULL,
|
||||
/* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name,
|
||||
/* disablement strs */ NOT_SHELL_name, NOT_SHELL_PFX },
|
||||
|
||||
{ /* entry idx, value */ INDEX_GENSHELL_OPT_VERSION, VALUE_GENSHELL_OPT_VERSION,
|
||||
/* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_VERSION,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ VER_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL },
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ VER_PROC,
|
||||
/* desc, NAME, name */ VER_DESC, NULL, VER_name,
|
||||
/* disablement strs */ NULL, NULL },
|
||||
|
||||
|
||||
|
||||
{ /* entry idx, value */ INDEX_GENSHELL_OPT_HELP, VALUE_GENSHELL_OPT_HELP,
|
||||
/* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_HELP,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ OPTST_IMM | OPTST_NO_INIT, 0,
|
||||
/* last opt argumnt */ { NULL },
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ doUsageOpt,
|
||||
/* desc, NAME, name */ HELP_DESC, NULL, HELP_name,
|
||||
/* disablement strs */ NULL, NULL },
|
||||
|
||||
{ /* entry idx, value */ INDEX_GENSHELL_OPT_MORE_HELP, VALUE_GENSHELL_OPT_MORE_HELP,
|
||||
/* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_MORE_HELP,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ MORE_HELP_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL },
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ optionPagedUsage,
|
||||
/* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name,
|
||||
/* disablement strs */ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Define the genshellopt Option Environment
|
||||
*/
|
||||
#define zPROGNAME (genshellopt_opt_strs+1102)
|
||||
#define zUsageTitle (genshellopt_opt_strs+1114)
|
||||
#define zRcName NULL
|
||||
#define apzHomeList NULL
|
||||
#define zBugsAddr (genshellopt_opt_strs+1235)
|
||||
#define zExplain (genshellopt_opt_strs+1271)
|
||||
#define zDetail (genshellopt_opt_strs+1452)
|
||||
#define zFullVersion (genshellopt_opt_strs+1676)
|
||||
/* extracted from optcode.tlib near line 350 */
|
||||
|
||||
#if defined(ENABLE_NLS)
|
||||
# define OPTPROC_BASE OPTPROC_TRANSLATE
|
||||
static tOptionXlateProc translate_option_strings;
|
||||
#else
|
||||
# define OPTPROC_BASE OPTPROC_NONE
|
||||
# define translate_option_strings NULL
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
|
||||
#define genshellopt_full_usage (NULL)
|
||||
|
||||
#define genshellopt_short_usage (NULL)
|
||||
|
||||
#endif /* not defined __doxygen__ */
|
||||
|
||||
/*
|
||||
* Create the static procedure(s) declared above.
|
||||
*/
|
||||
/**
|
||||
* The callout function that invokes the genshelloptUsage function.
|
||||
*
|
||||
* @param pOptions the AutoOpts option description structure
|
||||
* @param pOptDesc the descriptor for the "help" (usage) option.
|
||||
* @noreturn
|
||||
*/
|
||||
static void
|
||||
doUsageOpt(tOptions * pOptions, tOptDesc * pOptDesc)
|
||||
{
|
||||
genshelloptUsage(&genshelloptOptions, GENSHELLOPT_EXIT_SUCCESS);
|
||||
/* NOTREACHED */
|
||||
(void)pOptDesc;
|
||||
(void)pOptions;
|
||||
}
|
||||
/* extracted from optmain.tlib near line 1113 */
|
||||
|
||||
/**
|
||||
* The directory containing the data associated with genshellopt.
|
||||
*/
|
||||
#ifndef PKGDATADIR
|
||||
# define PKGDATADIR ""
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Information about the person or institution that packaged genshellopt
|
||||
* for the current distribution.
|
||||
*/
|
||||
#ifndef WITH_PACKAGER
|
||||
# define genshellopt_packager_info NULL
|
||||
#else
|
||||
static char const genshellopt_packager_info[] =
|
||||
"Packaged by " WITH_PACKAGER
|
||||
|
||||
# ifdef WITH_PACKAGER_VERSION
|
||||
" ("WITH_PACKAGER_VERSION")"
|
||||
# endif
|
||||
|
||||
# ifdef WITH_PACKAGER_BUG_REPORTS
|
||||
"\nReport genshellopt bugs to " WITH_PACKAGER_BUG_REPORTS
|
||||
# endif
|
||||
"\n";
|
||||
#endif
|
||||
#ifndef __doxygen__
|
||||
|
||||
#endif /* __doxygen__ */
|
||||
/**
|
||||
* The option definitions for genshellopt. The one structure that
|
||||
* binds them all.
|
||||
*/
|
||||
tOptions genshelloptOptions = {
|
||||
OPTIONS_STRUCT_VERSION,
|
||||
0, NULL, /* original argc + argv */
|
||||
( OPTPROC_BASE
|
||||
+ OPTPROC_ERRSTOP
|
||||
+ OPTPROC_SHORTOPT
|
||||
+ OPTPROC_LONGOPT
|
||||
+ OPTPROC_NO_REQ_OPT
|
||||
+ OPTPROC_NEGATIONS
|
||||
+ OPTPROC_NO_ARGS ),
|
||||
0, NULL, /* current option index, current option */
|
||||
NULL, NULL, zPROGNAME,
|
||||
zRcName, zCopyright, zLicenseDescrip,
|
||||
zFullVersion, apzHomeList, zUsageTitle,
|
||||
zExplain, zDetail, optDesc,
|
||||
zBugsAddr, /* address to send bugs to */
|
||||
NULL, NULL, /* extensions/saved state */
|
||||
genshelloptUsage, /* usage procedure */
|
||||
translate_option_strings, /* translation procedure */
|
||||
/*
|
||||
* Indexes to special options
|
||||
*/
|
||||
{ INDEX_GENSHELL_OPT_MORE_HELP, /* more-help option index */
|
||||
NO_EQUIVALENT, /* save option index */
|
||||
NO_EQUIVALENT, /* '-#' option index */
|
||||
NO_EQUIVALENT /* index of default opt */
|
||||
},
|
||||
5 /* full option count */, 2 /* user option count */,
|
||||
genshellopt_full_usage, genshellopt_short_usage,
|
||||
NULL, NULL,
|
||||
PKGDATADIR, genshellopt_packager_info
|
||||
};
|
||||
|
||||
#if ENABLE_NLS
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <autoopts/usage-txt.h>
|
||||
|
||||
static char* AO_gettext(char const* pz);
|
||||
static void coerce_it(void** s);
|
||||
|
||||
/**
|
||||
* AutoGen specific wrapper function for gettext.
|
||||
* It relies on the macro _() to convert from English to the target
|
||||
* language, then strdup-duplicates the result string.
|
||||
*
|
||||
* @param[in] pz the input text used as a lookup key.
|
||||
* @returns the translated text (if there is one),
|
||||
* or the original text (if not).
|
||||
*/
|
||||
static char *
|
||||
AO_gettext(char const* pz)
|
||||
{
|
||||
char* pzRes;
|
||||
if (pz == NULL)
|
||||
return NULL;
|
||||
pzRes = _(pz);
|
||||
if (pzRes == pz)
|
||||
return pzRes;
|
||||
pzRes = strdup(pzRes);
|
||||
if (pzRes == NULL) {
|
||||
fputs(_("No memory for duping translated strings\n"), stderr);
|
||||
exit(GENSHELLOPT_EXIT_FAILURE);
|
||||
}
|
||||
return pzRes;
|
||||
}
|
||||
|
||||
static void coerce_it(void** s) { *s = AO_gettext(*s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate all the translatable strings in the genshelloptOptions
|
||||
* structure defined above. This is done only once.
|
||||
*/
|
||||
static void
|
||||
translate_option_strings(void)
|
||||
{
|
||||
tOptions * const pOpt = &genshelloptOptions;
|
||||
|
||||
/*
|
||||
* Guard against re-translation. It won't work. The strings will have
|
||||
* been changed by the first pass through this code. One shot only.
|
||||
*/
|
||||
if (option_usage_text.field_ct != 0) {
|
||||
/*
|
||||
* Do the translations. The first pointer follows the field count
|
||||
* field. The field count field is the size of a pointer.
|
||||
*/
|
||||
tOptDesc * pOD = pOpt->pOptDesc;
|
||||
char ** ppz = (char**)(void*)&(option_usage_text);
|
||||
int ix = option_usage_text.field_ct;
|
||||
|
||||
do {
|
||||
ppz++;
|
||||
*ppz = AO_gettext(*ppz);
|
||||
} while (--ix > 0);
|
||||
|
||||
coerce_it((void*)&(pOpt->pzCopyright));
|
||||
coerce_it((void*)&(pOpt->pzCopyNotice));
|
||||
coerce_it((void*)&(pOpt->pzFullVersion));
|
||||
coerce_it((void*)&(pOpt->pzUsageTitle));
|
||||
coerce_it((void*)&(pOpt->pzExplain));
|
||||
coerce_it((void*)&(pOpt->pzDetail));
|
||||
coerce_it((void*)&(pOpt->pzPackager));
|
||||
option_usage_text.field_ct = 0;
|
||||
|
||||
for (ix = pOpt->optCt; ix > 0; ix--, pOD++)
|
||||
coerce_it((void*)&(pOD->pzText));
|
||||
}
|
||||
|
||||
if ((pOpt->fOptSet & OPTPROC_NXLAT_OPT_CFG) == 0) {
|
||||
tOptDesc * pOD = pOpt->pOptDesc;
|
||||
int ix;
|
||||
|
||||
for (ix = pOpt->optCt; ix > 0; ix--, pOD++) {
|
||||
coerce_it((void*)&(pOD->pz_Name));
|
||||
coerce_it((void*)&(pOD->pz_DisableName));
|
||||
coerce_it((void*)&(pOD->pz_DisablePfx));
|
||||
}
|
||||
/* prevent re-translation */
|
||||
genshelloptOptions.fOptSet |= OPTPROC_NXLAT_OPT_CFG | OPTPROC_NXLAT_OPT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* genshell.c ends here */
|
||||
@@ -0,0 +1,178 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (genshell.h)
|
||||
*
|
||||
* It has been AutoGen-ed May 6, 2012 at 04:20:59 PM by AutoGen 5.16pre36
|
||||
* From the definitions genshell.def
|
||||
* and the template file options
|
||||
*
|
||||
* Generated from AutoOpts 36:4:11 templates.
|
||||
*
|
||||
* AutoOpts is a copyrighted work. This header file is not encumbered
|
||||
* by AutoOpts licensing, but is provided under the licensing terms chosen
|
||||
* by the genshellopt author or copyright holder. AutoOpts is
|
||||
* licensed under the terms of the LGPL. The redistributable library
|
||||
* (``libopts'') is licensed under the terms of either the LGPL or, at the
|
||||
* users discretion, the BSD license. See the AutoOpts and/or libopts sources
|
||||
* for details.
|
||||
*
|
||||
* The genshellopt program is copyrighted and licensed
|
||||
* under the following terms:
|
||||
*
|
||||
* Copyright (C) 1999-2012 Bruce Korb, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* GNU General Public License, version 3 or later
|
||||
* <http://gnu.org/licenses/gpl.html>
|
||||
*
|
||||
* genshellopt is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* genshellopt is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* This file contains the programmatic interface to the Automated
|
||||
* Options generated for the genshellopt program.
|
||||
* These macros are documented in the AutoGen info file in the
|
||||
* "AutoOpts" chapter. Please refer to that doc for usage help.
|
||||
*/
|
||||
#ifndef AUTOOPTS_GENSHELL_H_GUARD
|
||||
#define AUTOOPTS_GENSHELL_H_GUARD 1
|
||||
#include <autoopts/options.h>
|
||||
|
||||
/*
|
||||
* Ensure that the library used for compiling this generated header is at
|
||||
* least as new as the version current when the header template was released
|
||||
* (not counting patch version increments). Also ensure that the oldest
|
||||
* tolerable version is at least as old as what was current when the header
|
||||
* template was released.
|
||||
*/
|
||||
#define AO_TEMPLATE_VERSION 147460
|
||||
#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \
|
||||
|| (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION)
|
||||
# error option template version mismatches autoopts/options.h header
|
||||
Choke Me.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumeration of each option:
|
||||
*/
|
||||
typedef enum {
|
||||
INDEX_GENSHELL_OPT_SCRIPT = 0,
|
||||
INDEX_GENSHELL_OPT_SHELL = 1,
|
||||
INDEX_GENSHELL_OPT_VERSION = 2,
|
||||
INDEX_GENSHELL_OPT_HELP = 3,
|
||||
INDEX_GENSHELL_OPT_MORE_HELP = 4
|
||||
} teGenshell_OptIndex;
|
||||
|
||||
#define GENSHELL_OPTION_CT 5
|
||||
#define GENSHELLOPT_VERSION "1"
|
||||
#define GENSHELLOPT_FULL_VERSION "genshellopt 1"
|
||||
|
||||
/*
|
||||
* Interface defines for all options. Replace "n" with the UPPER_CASED
|
||||
* option name (as in the teGenshell_OptIndex enumeration above).
|
||||
* e.g. HAVE_GENSHELL_OPT(SCRIPT)
|
||||
*/
|
||||
#define GENSHELL_DESC(n) (genshelloptOptions.pOptDesc[INDEX_GENSHELL_OPT_## n])
|
||||
#define HAVE_GENSHELL_OPT(n) (! UNUSED_OPT(& GENSHELL_DESC(n)))
|
||||
#define GENSHELL_OPT_ARG(n) (GENSHELL_DESC(n).optArg.argString)
|
||||
#define STATE_GENSHELL_OPT(n) (GENSHELL_DESC(n).fOptState & OPTST_SET_MASK)
|
||||
#define COUNT_GENSHELL_OPT(n) (GENSHELL_DESC(n).optOccCt)
|
||||
#define ISSEL_GENSHELL_OPT(n) (SELECTED_OPT(&GENSHELL_DESC(n)))
|
||||
#define ISUNUSED_GENSHELL_OPT(n) (UNUSED_OPT(& GENSHELL_DESC(n)))
|
||||
#define ENABLED_GENSHELL_OPT(n) (! DISABLED_OPT(& GENSHELL_DESC(n)))
|
||||
#define STACKCT_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->useCt)
|
||||
#define STACKLST_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->apzArgs)
|
||||
#define CLEAR_GENSHELL_OPT(n) STMTS( \
|
||||
GENSHELL_DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \
|
||||
if ((GENSHELL_DESC(n).fOptState & OPTST_INITENABLED) == 0) \
|
||||
GENSHELL_DESC(n).fOptState |= OPTST_DISABLED; \
|
||||
GENSHELL_DESC(n).optCookie = NULL )
|
||||
|
||||
/* * * * * *
|
||||
*
|
||||
* Enumeration of genshellopt exit codes
|
||||
*/
|
||||
typedef enum {
|
||||
GENSHELLOPT_EXIT_SUCCESS = 0,
|
||||
GENSHELLOPT_EXIT_FAILURE = 1,
|
||||
GENSHELLOPT_EXIT_LIBOPTS_FAILURE = 70
|
||||
} genshellopt_exit_code_t;
|
||||
/* * * * * *
|
||||
*
|
||||
* Interface defines for specific options.
|
||||
*/
|
||||
#define VALUE_GENSHELL_OPT_SCRIPT 'o'
|
||||
#define VALUE_GENSHELL_OPT_SHELL 's'
|
||||
#define VALUE_GENSHELL_OPT_HELP '?'
|
||||
#define VALUE_GENSHELL_OPT_MORE_HELP '!'
|
||||
#define VALUE_GENSHELL_OPT_VERSION 'v'
|
||||
/*
|
||||
* Interface defines not associated with particular options
|
||||
*/
|
||||
#define ERRSKIP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP)
|
||||
#define ERRSTOP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP)
|
||||
#define RESTART_GENSHELL_OPT(n) STMTS( \
|
||||
genshelloptOptions.curOptIdx = (n); \
|
||||
genshelloptOptions.pzCurOpt = NULL )
|
||||
#define START_GENSHELL_OPT RESTART_GENSHELL_OPT(1)
|
||||
#define GENSHELL_USAGE(c) (*genshelloptOptions.pUsageProc)(&genshelloptOptions, c)
|
||||
/* extracted from opthead.tlib near line 484 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* * * * * *
|
||||
*
|
||||
* Declare the genshellopt option descriptor.
|
||||
*/
|
||||
extern tOptions genshelloptOptions;
|
||||
|
||||
#if defined(ENABLE_NLS)
|
||||
# ifndef _
|
||||
# include <stdio.h>
|
||||
static inline char* aoGetsText(char const* pz) {
|
||||
if (pz == NULL) return NULL;
|
||||
return (char*)gettext(pz);
|
||||
}
|
||||
# define _(s) aoGetsText(s)
|
||||
# endif /* _() */
|
||||
|
||||
# define OPT_NO_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet |= \
|
||||
OPTPROC_NXLAT_OPT_CFG;)
|
||||
# define OPT_NO_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet |= \
|
||||
OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;)
|
||||
|
||||
# define OPT_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet &= \
|
||||
~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);)
|
||||
# define OPT_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet &= \
|
||||
~OPTPROC_NXLAT_OPT;)
|
||||
|
||||
#else /* ENABLE_NLS */
|
||||
# define OPT_NO_XLAT_CFG_NAMES
|
||||
# define OPT_NO_XLAT_OPT_NAMES
|
||||
|
||||
# define OPT_XLAT_CFG_NAMES
|
||||
# define OPT_XLAT_OPT_NAMES
|
||||
|
||||
# ifndef _
|
||||
# define _(_s) _s
|
||||
# endif
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* AUTOOPTS_GENSHELL_H_GUARD */
|
||||
/* genshell.h ends here */
|
||||
@@ -0,0 +1,45 @@
|
||||
#define AUTOOPTS_INTERNAL 1
|
||||
#include "autoopts/project.h"
|
||||
#define LOCAL static
|
||||
#include "ao-strs.h"
|
||||
#include "autoopts/options.h"
|
||||
#include "autoopts/usage-txt.h"
|
||||
#include "genshell.h"
|
||||
#include "xat-attribute.h"
|
||||
#include "value-type.h"
|
||||
#include "ao-strs.h"
|
||||
#include "ag-char-map.h"
|
||||
#include "autoopts.h"
|
||||
#include "proto.h"
|
||||
#include "parse-duration.c"
|
||||
#include "ao-strs.c"
|
||||
#include "value-type.c"
|
||||
#include "xat-attribute.c"
|
||||
#include "autoopts.c"
|
||||
#include "alias.c"
|
||||
#include "boolean.c"
|
||||
#include "check.c"
|
||||
#include "configfile.c"
|
||||
#include "cook.c"
|
||||
#include "enum.c"
|
||||
#include "env.c"
|
||||
#include "file.c"
|
||||
#include "find.c"
|
||||
#include "genshell.c"
|
||||
#include "load.c"
|
||||
#include "makeshell.c"
|
||||
#include "nested.c"
|
||||
#include "numeric.c"
|
||||
#include "pgusage.c"
|
||||
#include "putshell.c"
|
||||
#include "reset.c"
|
||||
#include "restore.c"
|
||||
#include "save.c"
|
||||
#include "sort.c"
|
||||
#include "stack.c"
|
||||
#include "streqvcmp.c"
|
||||
#include "text_mmap.c"
|
||||
#include "time.c"
|
||||
#include "tokenize.c"
|
||||
#include "usage.c"
|
||||
#include "version.c"
|
||||
+515
@@ -0,0 +1,515 @@
|
||||
|
||||
/**
|
||||
* \file load.c
|
||||
* Time-stamp: "2012-03-31 13:13:34 bkorb"
|
||||
*
|
||||
* This file contains the routines that deal with processing text strings
|
||||
* for options, either from a NUL-terminated string passed in or from an
|
||||
* rc/ini file.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static bool
|
||||
add_prog_path(char * pzBuf, int bufSize, char const * pzName,
|
||||
char const * pzProgPath);
|
||||
|
||||
static bool
|
||||
add_env_val(char * pzBuf, int bufSize, char const * pzName);
|
||||
|
||||
static char *
|
||||
assemble_arg_val(char * pzTxt, tOptionLoadMode mode);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/*=export_func optionMakePath
|
||||
* private:
|
||||
*
|
||||
* what: translate and construct a path
|
||||
* arg: + char* + pzBuf + The result buffer +
|
||||
* arg: + int + bufSize + The size of this buffer +
|
||||
* arg: + char const* + pzName + The input name +
|
||||
* arg: + char const* + pzProgPath + The full path of the current program +
|
||||
*
|
||||
* ret-type: bool
|
||||
* ret-desc: true if the name was handled, otherwise false.
|
||||
* If the name does not start with ``$'', then it is handled
|
||||
* simply by copying the input name to the output buffer and
|
||||
* resolving the name with either
|
||||
* @code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}.
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This routine will copy the @code{pzName} input name into the
|
||||
* @code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the
|
||||
* first character of the input name is a @code{'$'} character, then there
|
||||
* is special handling:
|
||||
* @*
|
||||
* @code{$$} is replaced with the directory name of the @code{pzProgPath},
|
||||
* searching @code{$PATH} if necessary.
|
||||
* @*
|
||||
* @code{$@} is replaced with the AutoGen package data installation directory
|
||||
* (aka @code{pkgdatadir}).
|
||||
* @*
|
||||
* @code{$NAME} is replaced by the contents of the @code{NAME} environment
|
||||
* variable. If not found, the search fails.
|
||||
*
|
||||
* Please note: both @code{$$} and @code{$NAME} must be at the start of the
|
||||
* @code{pzName} string and must either be the entire string or be followed
|
||||
* by the @code{'/'} (backslash on windows) character.
|
||||
*
|
||||
* err: @code{false} is returned if:
|
||||
* @*
|
||||
* @bullet{} The input name exceeds @code{bufSize} bytes.
|
||||
* @*
|
||||
* @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string
|
||||
* and the next character is not '/'.
|
||||
* @*
|
||||
* @bullet{} libopts was built without PKGDATADIR defined and @code{$@@}
|
||||
* was specified.
|
||||
* @*
|
||||
* @bullet{} @code{NAME} is not a known environment variable
|
||||
* @*
|
||||
* @bullet{} @code{canonicalize_file_name} or @code{realpath} return
|
||||
* errors (cannot resolve the resulting path).
|
||||
=*/
|
||||
bool
|
||||
optionMakePath(char * pzBuf, int bufSize, char const * pzName,
|
||||
char const * pzProgPath)
|
||||
{
|
||||
size_t name_len = strlen(pzName);
|
||||
|
||||
if (((size_t)bufSize <= name_len) || (name_len == 0))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* IF not an environment variable, just copy the data
|
||||
*/
|
||||
if (*pzName != '$') {
|
||||
char const* pzS = pzName;
|
||||
char* pzD = pzBuf;
|
||||
int ct = bufSize;
|
||||
|
||||
for (;;) {
|
||||
if ( (*(pzD++) = *(pzS++)) == NUL)
|
||||
break;
|
||||
if (--ct <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* IF the name starts with "$$", then it must be "$$" or
|
||||
* it must start with "$$/". In either event, replace the "$$"
|
||||
* with the path to the executable and append a "/" character.
|
||||
*/
|
||||
else switch (pzName[1]) {
|
||||
case NUL:
|
||||
return false;
|
||||
|
||||
case '$':
|
||||
if (! add_prog_path(pzBuf, bufSize, pzName, pzProgPath))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case '@':
|
||||
if (program_pkgdatadir[0] == NUL)
|
||||
return false;
|
||||
|
||||
if (snprintf(pzBuf, bufSize, "%s%s", program_pkgdatadir, pzName + 2)
|
||||
>= bufSize)
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! add_env_val(pzBuf, bufSize, pzName))
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(HAVE_CANONICALIZE_FILE_NAME)
|
||||
{
|
||||
char * pz = canonicalize_file_name(pzBuf);
|
||||
if (pz == NULL)
|
||||
return false;
|
||||
|
||||
name_len = strlen(pz);
|
||||
if (name_len >= (size_t)bufSize) {
|
||||
free(pz);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(pzBuf, pz, name_len + 1);
|
||||
free(pz);
|
||||
}
|
||||
|
||||
#elif defined(HAVE_REALPATH)
|
||||
{
|
||||
char z[PATH_MAX+1];
|
||||
|
||||
if (realpath(pzBuf, z) == NULL)
|
||||
return false;
|
||||
|
||||
name_len = strlen(z);
|
||||
if (name_len >= bufSize)
|
||||
return false;
|
||||
|
||||
memcpy(pzBuf, z, name_len + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
add_prog_path(char * pzBuf, int bufSize, char const * pzName,
|
||||
char const * pzProgPath)
|
||||
{
|
||||
char const* pzPath;
|
||||
char const* pz;
|
||||
int skip = 2;
|
||||
|
||||
switch (pzName[2]) {
|
||||
case DIRCH:
|
||||
skip = 3;
|
||||
case NUL:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the path is included in the program name.
|
||||
* If it is, we're done. Otherwise, we have to hunt
|
||||
* for the program using "pathfind".
|
||||
*/
|
||||
if (strchr(pzProgPath, DIRCH) != NULL)
|
||||
pzPath = pzProgPath;
|
||||
else {
|
||||
pzPath = pathfind(getenv("PATH"), (char*)pzProgPath, "rx");
|
||||
|
||||
if (pzPath == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
pz = strrchr(pzPath, DIRCH);
|
||||
|
||||
/*
|
||||
* IF we cannot find a directory name separator,
|
||||
* THEN we do not have a path name to our executable file.
|
||||
*/
|
||||
if (pz == NULL)
|
||||
return false;
|
||||
|
||||
pzName += skip;
|
||||
|
||||
/*
|
||||
* Concatenate the file name to the end of the executable path.
|
||||
* The result may be either a file or a directory.
|
||||
*/
|
||||
if ((pz - pzPath)+1 + strlen(pzName) >= (unsigned)bufSize)
|
||||
return false;
|
||||
|
||||
memcpy(pzBuf, pzPath, (size_t)((pz - pzPath)+1));
|
||||
strcpy(pzBuf + (pz - pzPath) + 1, pzName);
|
||||
|
||||
/*
|
||||
* If the "pzPath" path was gotten from "pathfind()", then it was
|
||||
* allocated and we need to deallocate it.
|
||||
*/
|
||||
if (pzPath != pzProgPath)
|
||||
AGFREE(pzPath);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
add_env_val(char * pzBuf, int bufSize, char const * pzName)
|
||||
{
|
||||
char * pzDir = pzBuf;
|
||||
|
||||
for (;;) {
|
||||
int ch = (int)*++pzName;
|
||||
if (! IS_VALUE_NAME_CHAR(ch))
|
||||
break;
|
||||
*(pzDir++) = (char)ch;
|
||||
}
|
||||
|
||||
if (pzDir == pzBuf)
|
||||
return false;
|
||||
|
||||
*pzDir = NUL;
|
||||
|
||||
pzDir = getenv(pzBuf);
|
||||
|
||||
/*
|
||||
* Environment value not found -- skip the home list entry
|
||||
*/
|
||||
if (pzDir == NULL)
|
||||
return false;
|
||||
|
||||
if (strlen(pzDir) + 1 + strlen(pzName) >= (unsigned)bufSize)
|
||||
return false;
|
||||
|
||||
sprintf(pzBuf, "%s%s", pzDir, pzName);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LOCAL void
|
||||
mungeString(char* pzTxt, tOptionLoadMode mode)
|
||||
{
|
||||
char * pzE;
|
||||
|
||||
if (mode == OPTION_LOAD_KEEP)
|
||||
return;
|
||||
|
||||
if (IS_WHITESPACE_CHAR(*pzTxt)) {
|
||||
char * pzS = SPN_WHITESPACE_CHARS(pzTxt+1);
|
||||
size_t l = strlen(pzS) + 1;
|
||||
memmove(pzTxt, pzS, l);
|
||||
pzE = pzTxt + l - 1;
|
||||
|
||||
} else
|
||||
pzE = pzTxt + strlen(pzTxt);
|
||||
|
||||
pzE = SPN_WHITESPACE_BACK(pzTxt, pzE);
|
||||
*pzE = NUL;
|
||||
|
||||
if (mode == OPTION_LOAD_UNCOOKED)
|
||||
return;
|
||||
|
||||
switch (*pzTxt) {
|
||||
default: return;
|
||||
case '"':
|
||||
case '\'': break;
|
||||
}
|
||||
|
||||
switch (pzE[-1]) {
|
||||
default: return;
|
||||
case '"':
|
||||
case '\'': break;
|
||||
}
|
||||
|
||||
(void)ao_string_cook(pzTxt, NULL);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
assemble_arg_val(char * pzTxt, tOptionLoadMode mode)
|
||||
{
|
||||
char* pzEnd = strpbrk(pzTxt, ARG_BREAK_STR);
|
||||
int space_break;
|
||||
|
||||
/*
|
||||
* Not having an argument to a configurable name is okay.
|
||||
*/
|
||||
if (pzEnd == NULL)
|
||||
return pzTxt + strlen(pzTxt);
|
||||
|
||||
/*
|
||||
* If we are keeping all whitespace, then the modevalue starts with the
|
||||
* character that follows the end of the configurable name, regardless
|
||||
* of which character caused it.
|
||||
*/
|
||||
if (mode == OPTION_LOAD_KEEP) {
|
||||
*(pzEnd++) = NUL;
|
||||
return pzEnd;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the name ended on a white space character, remember that
|
||||
* because we'll have to skip over an immediately following ':' or '='
|
||||
* (and the white space following *that*).
|
||||
*/
|
||||
space_break = IS_WHITESPACE_CHAR(*pzEnd);
|
||||
*(pzEnd++) = NUL;
|
||||
|
||||
pzEnd = SPN_WHITESPACE_CHARS(pzEnd);
|
||||
if (space_break && ((*pzEnd == ':') || (*pzEnd == '=')))
|
||||
pzEnd = SPN_WHITESPACE_CHARS(pzEnd+1);
|
||||
|
||||
return pzEnd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load an option from a block of text. The text must start with the
|
||||
* configurable/option name and be followed by its associated value.
|
||||
* That value may be processed in any of several ways. See "tOptionLoadMode"
|
||||
* in autoopts.h.
|
||||
*/
|
||||
LOCAL void
|
||||
loadOptionLine(
|
||||
tOptions* pOpts,
|
||||
tOptState* pOS,
|
||||
char* pzLine,
|
||||
tDirection direction,
|
||||
tOptionLoadMode load_mode )
|
||||
{
|
||||
pzLine = SPN_WHITESPACE_CHARS(pzLine);
|
||||
|
||||
{
|
||||
char* pzArg = assemble_arg_val(pzLine, load_mode);
|
||||
|
||||
if (! SUCCESSFUL(opt_find_long(pOpts, pzLine, pOS)))
|
||||
return;
|
||||
if (pOS->flags & OPTST_NO_INIT)
|
||||
return;
|
||||
pOS->pzOptArg = pzArg;
|
||||
}
|
||||
|
||||
switch (pOS->flags & (OPTST_IMM|OPTST_DISABLE_IMM)) {
|
||||
case 0:
|
||||
/*
|
||||
* The selected option has no immediate action.
|
||||
* THEREFORE, if the direction is PRESETTING
|
||||
* THEN we skip this option.
|
||||
*/
|
||||
if (PRESETTING(direction))
|
||||
return;
|
||||
break;
|
||||
|
||||
case OPTST_IMM:
|
||||
if (PRESETTING(direction)) {
|
||||
/*
|
||||
* We are in the presetting direction with an option we handle
|
||||
* immediately for enablement, but normally for disablement.
|
||||
* Therefore, skip if disabled.
|
||||
*/
|
||||
if ((pOS->flags & OPTST_DISABLED) == 0)
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* We are in the processing direction with an option we handle
|
||||
* immediately for enablement, but normally for disablement.
|
||||
* Therefore, skip if NOT disabled.
|
||||
*/
|
||||
if ((pOS->flags & OPTST_DISABLED) != 0)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTST_DISABLE_IMM:
|
||||
if (PRESETTING(direction)) {
|
||||
/*
|
||||
* We are in the presetting direction with an option we handle
|
||||
* immediately for disablement, but normally for disablement.
|
||||
* Therefore, skip if NOT disabled.
|
||||
*/
|
||||
if ((pOS->flags & OPTST_DISABLED) != 0)
|
||||
return;
|
||||
} else {
|
||||
/*
|
||||
* We are in the processing direction with an option we handle
|
||||
* immediately for disablement, but normally for disablement.
|
||||
* Therefore, skip if disabled.
|
||||
*/
|
||||
if ((pOS->flags & OPTST_DISABLED) == 0)
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTST_IMM|OPTST_DISABLE_IMM:
|
||||
/*
|
||||
* The selected option is always for immediate action.
|
||||
* THEREFORE, if the direction is PROCESSING
|
||||
* THEN we skip this option.
|
||||
*/
|
||||
if (PROCESSING(direction))
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix up the args.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
|
||||
if (*pOS->pzOptArg != NUL)
|
||||
return;
|
||||
pOS->pzOptArg = NULL;
|
||||
|
||||
} else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) {
|
||||
if (*pOS->pzOptArg == NUL)
|
||||
pOS->pzOptArg = NULL;
|
||||
else {
|
||||
AGDUPSTR(pOS->pzOptArg, pOS->pzOptArg, "option argument");
|
||||
pOS->flags |= OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (*pOS->pzOptArg == NUL)
|
||||
pOS->pzOptArg = zNil;
|
||||
else {
|
||||
AGDUPSTR(pOS->pzOptArg, pOS->pzOptArg, "option argument");
|
||||
pOS->flags |= OPTST_ALLOC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
tOptionLoadMode sv = option_load_mode;
|
||||
option_load_mode = load_mode;
|
||||
handle_opt(pOpts, pOS);
|
||||
option_load_mode = sv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionLoadLine
|
||||
*
|
||||
* what: process a string for an option name and value
|
||||
*
|
||||
* arg: tOptions*, pOpts, program options descriptor
|
||||
* arg: char const*, pzLine, NUL-terminated text
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This is a client program callable routine for setting options from, for
|
||||
* example, the contents of a file that they read in. Only one option may
|
||||
* appear in the text. It will be treated as a normal (non-preset) option.
|
||||
*
|
||||
* When passed a pointer to the option struct and a string, it will find
|
||||
* the option named by the first token on the string and set the option
|
||||
* argument to the remainder of the string. The caller must NUL terminate
|
||||
* the string. Any embedded new lines will be included in the option
|
||||
* argument. If the input looks like one or more quoted strings, then the
|
||||
* input will be "cooked". The "cooking" is identical to the string
|
||||
* formation used in AutoGen definition files (@pxref{basic expression}),
|
||||
* except that you may not use backquotes.
|
||||
*
|
||||
* err: Invalid options are silently ignored. Invalid option arguments
|
||||
* will cause a warning to print, but the function should return.
|
||||
=*/
|
||||
void
|
||||
optionLoadLine(tOptions * pOpts, char const * pzLine)
|
||||
{
|
||||
tOptState st = OPTSTATE_INITIALIZER(SET);
|
||||
char* pz;
|
||||
AGDUPSTR(pz, pzLine, "user option line");
|
||||
loadOptionLine(pOpts, &st, pz, DIRECTION_PROCESS, OPTION_LOAD_COOKED);
|
||||
AGFREE(pz);
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/load.c */
|
||||
@@ -0,0 +1,583 @@
|
||||
dnl -*- buffer-read-only: t -*- vi: set ro:
|
||||
dnl
|
||||
dnl DO NOT EDIT THIS FILE (libopts.m4)
|
||||
dnl
|
||||
dnl It has been AutoGen-ed May 6, 2012 at 04:20:55 PM by AutoGen 5.16pre36
|
||||
dnl From the definitions libopts.def
|
||||
dnl and the template file conftest.tpl
|
||||
dnl
|
||||
dnl do always before generated macros:
|
||||
dnl
|
||||
AC_DEFUN([INVOKE_LIBOPTS_MACROS_FIRST],[
|
||||
AC_REQUIRE([AC_HEADER_STDC])
|
||||
AC_HEADER_DIRENT
|
||||
|
||||
# =================
|
||||
# AC_CHECK_HEADERS
|
||||
# =================
|
||||
AC_CHECK_HEADERS([ \
|
||||
sys/mman.h sys/param.h sys/poll.h sys/procset.h \
|
||||
sys/select.h sys/socket.h sys/stropts.h sys/time.h \
|
||||
sys/un.h sys/wait.h dlfcn.h errno.h \
|
||||
fcntl.h libgen.h memory.h netinet/in.h \
|
||||
setjmp.h stdbool.h sysexits.h unistd.h \
|
||||
utime.h])
|
||||
|
||||
AC_CHECK_HEADERS([stdarg.h varargs.h],
|
||||
[lo_have_arg_hdr=true;break],
|
||||
[lo_have_arg_hdr=false])
|
||||
|
||||
AC_CHECK_HEADERS([string.h strings.h],
|
||||
[lo_have_str_hdr=true;break],
|
||||
[lo_have_str_hdr=false])
|
||||
|
||||
AC_CHECK_HEADERS([limits.h sys/limits.h values.h],
|
||||
[lo_have_lim_hdr=true;break],
|
||||
[lo_have_lim_hdr=false])
|
||||
|
||||
AC_CHECK_HEADERS([inttypes.h stdint.h],
|
||||
[lo_have_typ_hdr=true;break],
|
||||
[lo_have_typ_hdr=false])
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# check for various programs used during the build.
|
||||
# On OS/X, "wchar.h" needs "runetype.h" to work properly.
|
||||
# ----------------------------------------------------------------------
|
||||
AC_CHECK_HEADERS([runetype.h wchar.h], [], [],[
|
||||
AC_INCLUDES_DEFAULT
|
||||
#if HAVE_RUNETYPE_H
|
||||
# include <runetype.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# --------------------------------------------
|
||||
# Verify certain entries from AC_CHECK_HEADERS
|
||||
# --------------------------------------------
|
||||
[for f in sys_types sys_mman sys_param sys_stat sys_wait \
|
||||
string errno stdlib memory setjmp
|
||||
do eval as_ac_var=\${ac_cv_header_${f}_h+set}
|
||||
test "${as_ac_var}" = set || {
|
||||
]AC_MSG_ERROR([You must have ${f}.h on your system])[
|
||||
}
|
||||
done
|
||||
|
||||
${lo_have_arg_hdr} || \
|
||||
]AC_MSG_ERROR([You must have stdarg.h or varargs.h on your system])[
|
||||
|
||||
${lo_have_str_hdr} || \
|
||||
]AC_MSG_ERROR([You must have string.h or strings.h on your system])[
|
||||
|
||||
${lo_have_lim_hdr} || \
|
||||
]AC_MSG_ERROR(
|
||||
[You must have one of limits.h, sys/limits.h or values.h])[
|
||||
|
||||
${lo_have_typ_hdr} || \
|
||||
]AC_MSG_ERROR([You must have inttypes.h or stdint.h on your system])
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Checks for typedefs
|
||||
# ----------------------------------------------------------------------
|
||||
AC_CHECK_TYPES(wchar_t)
|
||||
AC_CHECK_TYPES(wint_t, [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#if HAVE_RUNETYPE_H
|
||||
# include <runetype.h>
|
||||
#endif
|
||||
#if HAVE_WCHAR_H
|
||||
# include <wchar.h>
|
||||
#endif
|
||||
])
|
||||
AC_CHECK_TYPES([int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
|
||||
intptr_t, uintptr_t, uint_t, pid_t, size_t])
|
||||
AC_CHECK_SIZEOF(char*, 8)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
AC_CHECK_SIZEOF(long, 8)
|
||||
AC_CHECK_SIZEOF(short, 2)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# AC_CHECK_LIB for SVR4 libgen, and use it if it defines pathfind.
|
||||
# ----------------------------------------------------------------------
|
||||
AC_CHECK_LIB(gen, pathfind)
|
||||
AC_FUNC_VPRINTF
|
||||
AC_FUNC_FORK
|
||||
AC_CHECK_FUNCS([mmap canonicalize_file_name snprintf strdup strchr \
|
||||
strrchr strsignal fchmod fstat chmod])
|
||||
AC_PROG_SED
|
||||
[while :
|
||||
do
|
||||
POSIX_SHELL=`which bash`
|
||||
test -x "$POSIX_SHELL" && break
|
||||
POSIX_SHELL=`which dash`
|
||||
test -x "$POSIX_SHELL" && break
|
||||
POSIX_SHELL=/usr/xpg4/bin/sh
|
||||
test -x "$POSIX_SHELL" && break
|
||||
POSIX_SHELL=`/bin/sh -c '
|
||||
exec 2>/dev/null
|
||||
if ! true ; then exit 1 ; fi
|
||||
echo /bin/sh'`
|
||||
test -x "$POSIX_SHELL" && break
|
||||
]AC_ERROR([Cannot locate a working POSIX shell])[
|
||||
done]
|
||||
AC_DEFINE_UNQUOTED([POSIX_SHELL], ["${POSIX_SHELL}"],
|
||||
[define to a working POSIX compliant shell])
|
||||
AC_SUBST([POSIX_SHELL])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl @synopsis INVOKE_LIBOPTS_MACROS
|
||||
dnl
|
||||
dnl This macro will invoke the AutoConf macros specified in libopts.def
|
||||
dnl that have not been disabled with "omit-invocation".
|
||||
dnl
|
||||
AC_DEFUN([LIBOPTS_WITH_REGEX_HEADER],[
|
||||
AC_ARG_WITH([regex-header],
|
||||
AS_HELP_STRING([--with-regex-header], [a reg expr header is specified]),
|
||||
[libopts_cv_with_regex_header=${with_regex_header}],
|
||||
AC_CACHE_CHECK([whether a reg expr header is specified], libopts_cv_with_regex_header,
|
||||
libopts_cv_with_regex_header=no)
|
||||
) # end of AC_ARG_WITH
|
||||
if test "X${libopts_cv_with_regex_header}" != Xno
|
||||
then
|
||||
AC_DEFINE_UNQUOTED([REGEX_HEADER],[<${libopts_cv_with_regex_header}>])
|
||||
else
|
||||
AC_DEFINE([REGEX_HEADER],[<regex.h>],[name of regex header file])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_WITH_REGEX_HEADER
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_WITHLIB_REGEX],[
|
||||
AC_ARG_WITH([libregex],
|
||||
AS_HELP_STRING([--with-libregex], [libregex installation prefix]),
|
||||
[libopts_cv_with_libregex_root=${with_libregex}],
|
||||
AC_CACHE_CHECK([whether with-libregex was specified], libopts_cv_with_libregex_root,
|
||||
libopts_cv_with_libregex_root=no)
|
||||
) # end of AC_ARG_WITH libregex
|
||||
|
||||
if test "${with_libregex+set}" = set && \
|
||||
test "X${withval}" = Xno
|
||||
then ## disabled by request
|
||||
libopts_cv_with_libregex_root=no
|
||||
libopts_cv_with_libregex_cflags=no
|
||||
libopts_cv_with_libregex_libs=no
|
||||
else
|
||||
|
||||
AC_ARG_WITH([libregex-cflags],
|
||||
AS_HELP_STRING([--with-libregex-cflags], [libregex compile flags]),
|
||||
[libopts_cv_with_libregex_cflags=${with_libregex_cflags}],
|
||||
AC_CACHE_CHECK([whether with-libregex-cflags was specified], libopts_cv_with_libregex_cflags,
|
||||
libopts_cv_with_libregex_cflags=no)
|
||||
) # end of AC_ARG_WITH libregex-cflags
|
||||
|
||||
AC_ARG_WITH([libregex-libs],
|
||||
AS_HELP_STRING([--with-libregex-libs], [libregex link command arguments]),
|
||||
[libopts_cv_with_libregex_libs=${with_libregex_libs}],
|
||||
AC_CACHE_CHECK([whether with-libregex-libs was specified], libopts_cv_with_libregex_libs,
|
||||
libopts_cv_with_libregex_libs=no)
|
||||
) # end of AC_ARG_WITH libregex-libs
|
||||
|
||||
case "X${libopts_cv_with_libregex_cflags}" in
|
||||
Xyes|Xno|X )
|
||||
case "X${libopts_cv_with_libregex_root}" in
|
||||
Xyes|Xno|X ) libopts_cv_with_libregex_cflags=no ;;
|
||||
* ) libopts_cv_with_libregex_cflags=-I${libopts_cv_with_libregex_root}/include ;;
|
||||
esac
|
||||
esac
|
||||
case "X${libopts_cv_with_libregex_libs}" in
|
||||
Xyes|Xno|X )
|
||||
case "X${libopts_cv_with_libregex_root}" in
|
||||
Xyes|Xno|X ) libopts_cv_with_libregex_libs=no ;;
|
||||
* ) libopts_cv_with_libregex_libs="-L${libopts_cv_with_libregex_root}/lib -lregex";;
|
||||
esac
|
||||
esac
|
||||
libopts_save_CPPFLAGS="${CPPFLAGS}"
|
||||
libopts_save_LIBS="${LIBS}"
|
||||
fi ## disabled by request
|
||||
|
||||
case "X${libopts_cv_with_libregex_cflags}" in
|
||||
Xyes|Xno|X )
|
||||
libopts_cv_with_libregex_cflags="" ;;
|
||||
* ) CPPFLAGS="${CPPFLAGS} ${libopts_cv_with_libregex_cflags}" ;;
|
||||
esac
|
||||
case "X${libopts_cv_with_libregex_libs}" in
|
||||
Xyes|Xno|X )
|
||||
libopts_cv_with_libregex_libs="" ;;
|
||||
* )
|
||||
LIBS="${LIBS} ${libopts_cv_with_libregex_libs}" ;;
|
||||
esac
|
||||
LIBREGEX_CFLAGS=""
|
||||
LIBREGEX_LIBS=""
|
||||
AC_MSG_CHECKING([whether libregex functions properly])
|
||||
AC_CACHE_VAL([libopts_cv_with_libregex],[
|
||||
AC_TRY_RUN([@%:@include <stdio.h>
|
||||
@%:@include <stdlib.h>
|
||||
@%:@include <sys/types.h>
|
||||
@%:@include REGEX_HEADER
|
||||
static regex_t re;
|
||||
void comp_re( char const* pzPat ) {
|
||||
int res = regcomp( &re, pzPat, REG_EXTENDED|REG_ICASE|REG_NEWLINE );
|
||||
if (res == 0) return;
|
||||
exit( res ); }
|
||||
int main() {
|
||||
regmatch_t m@<:@2@:>@;
|
||||
comp_re( "^.*\@S|@" );
|
||||
comp_re( "()|no.*" );
|
||||
comp_re( "." );
|
||||
if (regexec( &re, "X", 2, m, 0 ) != 0) return 1;
|
||||
if ((m@<:@0@:>@.rm_so != 0) || (m@<:@0@:>@.rm_eo != 1)) {
|
||||
fputs( "error: regex -->.<-- did not match\n", stderr );
|
||||
return 1;
|
||||
}
|
||||
return 0; }],
|
||||
[libopts_cv_with_libregex=yes], [libopts_cv_with_libregex=no],
|
||||
[libopts_cv_with_libregex=no]) # end of AC_TRY_RUN
|
||||
]) # end of AC_CACHE_VAL for libopts_cv_with_libregex
|
||||
AC_MSG_RESULT([${libopts_cv_with_libregex}])
|
||||
if test "X${libopts_cv_with_libregex}" != Xno
|
||||
then
|
||||
AC_DEFINE([WITH_LIBREGEX],[1],
|
||||
[Define this if a working libregex can be found])
|
||||
else
|
||||
CPPFLAGS="${libopts_save_CPPFLAGS}"
|
||||
LIBS="${libopts_save_LIBS}"
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_WITHLIB_REGEX
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_RUN_PATHFIND],[
|
||||
AC_MSG_CHECKING([whether pathfind(3) works])
|
||||
AC_CACHE_VAL([libopts_cv_run_pathfind],[
|
||||
AC_TRY_RUN([@%:@include <string.h>
|
||||
@%:@include <stdlib.h>
|
||||
int main (int argc, char** argv) {
|
||||
char* pz = pathfind( getenv( "PATH" ), "sh", "x" );
|
||||
return (pz == 0) ? 1 : 0;
|
||||
}],
|
||||
[libopts_cv_run_pathfind=yes],[libopts_cv_run_pathfind=no],[libopts_cv_run_pathfind=no]
|
||||
) # end of TRY_RUN
|
||||
]) # end of AC_CACHE_VAL for libopts_cv_run_pathfind
|
||||
AC_MSG_RESULT([${libopts_cv_run_pathfind}])
|
||||
if test "X${libopts_cv_run_pathfind}" != Xno
|
||||
then
|
||||
AC_DEFINE([HAVE_PATHFIND],[1],
|
||||
[Define this if pathfind(3) works])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_RUN_PATHFIND
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_TEST_DEV_ZERO],[
|
||||
AC_MSG_CHECKING([whether /dev/zero is readable device])
|
||||
AC_CACHE_VAL([libopts_cv_test_dev_zero],[
|
||||
libopts_cv_test_dev_zero=`exec 2> /dev/null
|
||||
dzero=\`ls -lL /dev/zero | egrep ^c......r\`
|
||||
test -z "${dzero}" && exit 1
|
||||
echo ${dzero}`
|
||||
if test $? -ne 0 || test -z "$libopts_cv_test_dev_zero"
|
||||
then libopts_cv_test_dev_zero=no
|
||||
fi
|
||||
]) # end of CACHE_VAL of libopts_cv_test_dev_zero
|
||||
AC_MSG_RESULT([${libopts_cv_test_dev_zero}])
|
||||
if test "X${libopts_cv_test_dev_zero}" != Xno
|
||||
then
|
||||
AC_DEFINE([HAVE_DEV_ZERO],[1],
|
||||
[Define this if /dev/zero is readable device])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_TEST_DEV_ZERO
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_RUN_REALPATH],[
|
||||
AC_MSG_CHECKING([whether we have a functional realpath(3C)])
|
||||
AC_CACHE_VAL([libopts_cv_run_realpath],[
|
||||
AC_TRY_RUN([@%:@include <limits.h>
|
||||
@%:@include <stdlib.h>
|
||||
int main (int argc, char** argv) {
|
||||
@%:@ifndef PATH_MAX
|
||||
choke me!!
|
||||
@%:@else
|
||||
char zPath@<:@PATH_MAX+1@:>@;
|
||||
@%:@endif
|
||||
char *pz = realpath(argv@<:@0@:>@, zPath);
|
||||
return (pz == zPath) ? 0 : 1;
|
||||
}],
|
||||
[libopts_cv_run_realpath=yes],[libopts_cv_run_realpath=no],[libopts_cv_run_realpath=no]
|
||||
) # end of TRY_RUN
|
||||
]) # end of AC_CACHE_VAL for libopts_cv_run_realpath
|
||||
AC_MSG_RESULT([${libopts_cv_run_realpath}])
|
||||
if test "X${libopts_cv_run_realpath}" != Xno
|
||||
then
|
||||
AC_DEFINE([HAVE_REALPATH],[1],
|
||||
[Define this if we have a functional realpath(3C)])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_RUN_REALPATH
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_RUN_STRFTIME],[
|
||||
AC_MSG_CHECKING([whether strftime() works])
|
||||
AC_CACHE_VAL([libopts_cv_run_strftime],[
|
||||
AC_TRY_RUN([@%:@include <time.h>
|
||||
@%:@include <string.h>
|
||||
char t_buf@<:@ 64 @:>@;
|
||||
int main() {
|
||||
static char const z@<:@@:>@ = "Thursday Aug 28 240";
|
||||
struct tm tm;
|
||||
tm.tm_sec = 36; /* seconds after the minute @<:@0, 61@:>@ */
|
||||
tm.tm_min = 44; /* minutes after the hour @<:@0, 59@:>@ */
|
||||
tm.tm_hour = 12; /* hour since midnight @<:@0, 23@:>@ */
|
||||
tm.tm_mday = 28; /* day of the month @<:@1, 31@:>@ */
|
||||
tm.tm_mon = 7; /* months since January @<:@0, 11@:>@ */
|
||||
tm.tm_year = 86; /* years since 1900 */
|
||||
tm.tm_wday = 4; /* days since Sunday @<:@0, 6@:>@ */
|
||||
tm.tm_yday = 239; /* days since January 1 @<:@0, 365@:>@ */
|
||||
tm.tm_isdst = 1; /* flag for daylight savings time */
|
||||
strftime( t_buf, sizeof( t_buf ), "%A %b %d %j", &tm );
|
||||
return (strcmp( t_buf, z ) != 0); }],
|
||||
[libopts_cv_run_strftime=yes],[libopts_cv_run_strftime=no],[libopts_cv_run_strftime=no]
|
||||
) # end of TRY_RUN
|
||||
]) # end of AC_CACHE_VAL for libopts_cv_run_strftime
|
||||
AC_MSG_RESULT([${libopts_cv_run_strftime}])
|
||||
if test "X${libopts_cv_run_strftime}" != Xno
|
||||
then
|
||||
AC_DEFINE([HAVE_STRFTIME],[1],
|
||||
[Define this if strftime() works])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_RUN_STRFTIME
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_RUN_FOPEN_BINARY],[
|
||||
AC_MSG_CHECKING([whether fopen accepts "b" mode])
|
||||
AC_CACHE_VAL([libopts_cv_run_fopen_binary],[
|
||||
AC_TRY_RUN([@%:@include <stdio.h>
|
||||
int main (int argc, char** argv) {
|
||||
FILE* fp = fopen("conftest.@S|@ac_ext", "rb");
|
||||
return (fp == NULL) ? 1 : fclose(fp); }],
|
||||
[libopts_cv_run_fopen_binary=yes],[libopts_cv_run_fopen_binary=no],[libopts_cv_run_fopen_binary=no]
|
||||
) # end of TRY_RUN
|
||||
]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_binary
|
||||
AC_MSG_RESULT([${libopts_cv_run_fopen_binary}])
|
||||
if test "X${libopts_cv_run_fopen_binary}" != Xno
|
||||
then
|
||||
AC_DEFINE([FOPEN_BINARY_FLAG],"b",
|
||||
[fopen(3) accepts a 'b' in the mode flag])
|
||||
else
|
||||
AC_DEFINE([FOPEN_BINARY_FLAG],"",
|
||||
[fopen(3) accepts a 'b' in the mode flag])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_BINARY
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_RUN_FOPEN_TEXT],[
|
||||
AC_MSG_CHECKING([whether fopen accepts "t" mode])
|
||||
AC_CACHE_VAL([libopts_cv_run_fopen_text],[
|
||||
AC_TRY_RUN([@%:@include <stdio.h>
|
||||
int main (int argc, char** argv) {
|
||||
FILE* fp = fopen("conftest.@S|@ac_ext", "rt");
|
||||
return (fp == NULL) ? 1 : fclose(fp); }],
|
||||
[libopts_cv_run_fopen_text=yes],[libopts_cv_run_fopen_text=no],[libopts_cv_run_fopen_text=no]
|
||||
) # end of TRY_RUN
|
||||
]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_text
|
||||
AC_MSG_RESULT([${libopts_cv_run_fopen_text}])
|
||||
if test "X${libopts_cv_run_fopen_text}" != Xno
|
||||
then
|
||||
AC_DEFINE([FOPEN_TEXT_FLAG],"t",
|
||||
[fopen(3) accepts a 't' in the mode flag])
|
||||
else
|
||||
AC_DEFINE([FOPEN_TEXT_FLAG],"",
|
||||
[fopen(3) accepts a 't' in the mode flag])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_TEXT
|
||||
|
||||
|
||||
AC_DEFUN([LIBOPTS_DISABLE_OPTIONAL_ARGS],[
|
||||
AC_ARG_ENABLE([optional-args],
|
||||
AS_HELP_STRING([--disable-optional-args], [not wanting optional option args]),
|
||||
[libopts_cv_enable_optional_args=${enable_optional_args}],
|
||||
AC_CACHE_CHECK([whether not wanting optional option args], libopts_cv_enable_optional_args,
|
||||
libopts_cv_enable_optional_args=yes)
|
||||
) # end of AC_ARG_ENABLE
|
||||
if test "X${libopts_cv_enable_optional_args}" = Xno
|
||||
then
|
||||
AC_DEFINE([NO_OPTIONAL_OPT_ARGS], [1],
|
||||
[Define this if optional arguments are disallowed])
|
||||
fi
|
||||
|
||||
]) # end of AC_DEFUN of LIBOPTS_DISABLE_OPTIONAL_ARGS
|
||||
|
||||
|
||||
AC_DEFUN([INVOKE_LIBOPTS_MACROS],[
|
||||
AC_REQUIRE([INVOKE_LIBOPTS_MACROS_FIRST])
|
||||
# Check to see if a reg expr header is specified.
|
||||
LIBOPTS_WITH_REGEX_HEADER
|
||||
|
||||
# Check to see if a working libregex can be found.
|
||||
LIBOPTS_WITHLIB_REGEX
|
||||
|
||||
# Check to see if pathfind(3) works.
|
||||
LIBOPTS_RUN_PATHFIND
|
||||
|
||||
# Check to see if /dev/zero is readable device.
|
||||
LIBOPTS_TEST_DEV_ZERO
|
||||
|
||||
# Check to see if we have a functional realpath(3C).
|
||||
LIBOPTS_RUN_REALPATH
|
||||
|
||||
# Check to see if strftime() works.
|
||||
LIBOPTS_RUN_STRFTIME
|
||||
|
||||
# Check to see if fopen accepts "b" mode.
|
||||
LIBOPTS_RUN_FOPEN_BINARY
|
||||
|
||||
# Check to see if fopen accepts "t" mode.
|
||||
LIBOPTS_RUN_FOPEN_TEXT
|
||||
|
||||
# Check to see if not wanting optional option args.
|
||||
LIBOPTS_DISABLE_OPTIONAL_ARGS
|
||||
|
||||
]) # end AC_DEFUN of INVOKE_LIBOPTS_MACROS
|
||||
|
||||
dnl @synopsis LIBOPTS_CHECK
|
||||
dnl
|
||||
dnl Time-stamp: "2012-02-25 12:54:32 bkorb"
|
||||
dnl
|
||||
dnl If autoopts-config works, add the linking information to LIBS.
|
||||
dnl Otherwise, add ``libopts-${ao_rev}'' to SUBDIRS and run all
|
||||
dnl the config tests that the library needs. Invoke the
|
||||
dnl "INVOKE_LIBOPTS_MACROS" macro iff we are building libopts.
|
||||
dnl
|
||||
dnl This file is part of AutoGen.
|
||||
dnl AutoGen Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
dnl
|
||||
dnl AutoGen is free software: you can redistribute it and/or modify it
|
||||
dnl under the terms of the GNU General Public License as published by the
|
||||
dnl Free Software Foundation, either version 3 of the License, or
|
||||
dnl (at your option) any later version.
|
||||
dnl
|
||||
dnl AutoGen is distributed in the hope that it will be useful, but
|
||||
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
dnl See the GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License along
|
||||
dnl with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
dnl
|
||||
dnl Default to system libopts
|
||||
dnl
|
||||
AC_DEFUN([LIBOPTS_CHECK_COMMON],[
|
||||
AC_REQUIRE([INVOKE_LIBOPTS_MACROS_FIRST])
|
||||
[NEED_LIBOPTS_DIR='']
|
||||
m4_pushdef([AO_Libopts_Dir],
|
||||
[ifelse($1, , [libopts], [$1])])
|
||||
AC_ARG_ENABLE([local-libopts],
|
||||
AC_HELP_STRING([--enable-local-libopts],
|
||||
[Use the supplied libopts tearoff code]),[
|
||||
if test x$enableval = xyes ; then
|
||||
AC_MSG_NOTICE([Using supplied libopts tearoff])
|
||||
LIBOPTS_CFLAGS='-I$(top_srcdir)/AO_Libopts_Dir'
|
||||
NEED_LIBOPTS_DIR=true
|
||||
LIBOPTS_LDADD='$(top_builddir)/AO_Libopts_Dir/libopts.la'
|
||||
fi])
|
||||
|
||||
AC_ARG_ENABLE([libopts-install],
|
||||
AC_HELP_STRING([--enable-libopts-install],
|
||||
[Install libopts with client installation]))
|
||||
AM_CONDITIONAL([INSTALL_LIBOPTS],[test "X${enable_libopts_install}" = Xyes])
|
||||
|
||||
[if test -z "${NEED_LIBOPTS_DIR}" ; then]
|
||||
AC_MSG_CHECKING([whether autoopts-config can be found])
|
||||
AC_ARG_WITH([autoopts-config],
|
||||
AC_HELP_STRING([--with-autoopts-config],
|
||||
[specify the config-info script]),
|
||||
[lo_cv_with_autoopts_config=${with_autoopts_config}],
|
||||
AC_CACHE_CHECK([whether autoopts-config is specified],
|
||||
[lo_cv_with_autoopts_config],
|
||||
[if autoopts-config --help 2>/dev/null 1>&2
|
||||
then lo_cv_with_autoopts_config=autoopts-config
|
||||
elif libopts-config --help 2>/dev/null 1>&2
|
||||
then lo_cv_with_autoopts_config=libopts-config
|
||||
else lo_cv_with_autoopts_config=no ; fi])
|
||||
) # end of AC_ARG_WITH
|
||||
|
||||
AC_CACHE_VAL([lo_cv_test_autoopts],[
|
||||
if test -z "${lo_cv_with_autoopts_config}" \
|
||||
-o X"${lo_cv_with_autoopts_config}" = Xno
|
||||
then
|
||||
if autoopts-config --help 2>/dev/null 1>&2
|
||||
then lo_cv_with_autoopts_config=autoopts-config
|
||||
elif libopts-config --help 2>/dev/null 1>&2
|
||||
then lo_cv_with_autoopts_config=libopts-config
|
||||
else lo_cv_with_autoopts_config=false ; fi
|
||||
fi
|
||||
lo_cv_test_autoopts=`
|
||||
${lo_cv_with_autoopts_config} --libs` 2> /dev/null
|
||||
if test $? -ne 0 -o -z "${lo_cv_test_autoopts}"
|
||||
then lo_cv_test_autoopts=no ; fi
|
||||
]) # end of CACHE_VAL
|
||||
AC_MSG_RESULT([${lo_cv_test_autoopts}])
|
||||
|
||||
[if test "X${lo_cv_test_autoopts}" != Xno
|
||||
then
|
||||
LIBOPTS_LDADD="${lo_cv_test_autoopts}"
|
||||
LIBOPTS_CFLAGS="`${lo_cv_with_autoopts_config} --cflags`"
|
||||
else
|
||||
LIBOPTS_LDADD='$(top_builddir)/]AO_Libopts_Dir[/libopts.la'
|
||||
LIBOPTS_CFLAGS='-I$(top_srcdir)/]AO_Libopts_Dir['
|
||||
NEED_LIBOPTS_DIR=true
|
||||
fi
|
||||
fi # end of if test -z "${NEED_LIBOPTS_DIR}"
|
||||
if test -n "${LIBOPTS_BUILD_BLOCKED}" ; then
|
||||
NEED_LIBOPTS_DIR=''
|
||||
fi]
|
||||
AM_CONDITIONAL([NEED_LIBOPTS], [test -n "${NEED_LIBOPTS_DIR}"])
|
||||
AC_SUBST(LIBOPTS_LDADD)
|
||||
AC_SUBST(LIBOPTS_CFLAGS)
|
||||
AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir)
|
||||
m4_popdef([AO_Libopts_Dir])
|
||||
[# end of AC_DEFUN of LIBOPTS_CHECK_COMMON]
|
||||
])
|
||||
dnl
|
||||
dnl AC_CONFIG_FILES conditionalization requires using AM_COND_IF, however
|
||||
dnl AM_COND_IF is new to Automake 1.11. To use it on new Automake without
|
||||
dnl requiring same, a fallback implementation for older Automake is provided.
|
||||
dnl Note that disabling of AC_CONFIG_FILES requires Automake 1.11, this code
|
||||
dnl is correct only in terms of m4sh generated script.
|
||||
dnl
|
||||
m4_ifndef([AM_COND_IF],
|
||||
[AC_DEFUN([AM_COND_IF], [
|
||||
if test -z "$$1_TRUE"; then :
|
||||
m4_n([$2])[]dnl
|
||||
m4_ifval([$3],[
|
||||
else
|
||||
$3
|
||||
])dnl
|
||||
fi[]dnl
|
||||
])dnl
|
||||
])
|
||||
dnl
|
||||
AC_DEFUN([LIBOPTS_CHECK_NOBUILD], [
|
||||
m4_pushdef([AO_Libopts_Dir],
|
||||
[ifelse($1, , [libopts], [$1])])
|
||||
LIBOPTS_BUILD_BLOCKED=true
|
||||
LIBOPTS_CHECK_COMMON(AO_Libopts_Dir)
|
||||
m4_popdef([AO_Libopts_Dir])dnl
|
||||
# end of AC_DEFUN of LIBOPTS_CHECK_NOBUILD
|
||||
])
|
||||
dnl
|
||||
AC_DEFUN([LIBOPTS_CHECK], [
|
||||
m4_pushdef([AO_Libopts_Dir],
|
||||
[ifelse($1, , [libopts], [$1])])
|
||||
LIBOPTS_BUILD_BLOCKED=''
|
||||
LIBOPTS_CHECK_COMMON(AO_Libopts_Dir)
|
||||
AM_COND_IF([NEED_LIBOPTS], [
|
||||
INVOKE_LIBOPTS_MACROS
|
||||
AC_CONFIG_FILES(AO_Libopts_Dir/Makefile)
|
||||
])dnl
|
||||
m4_popdef([AO_Libopts_Dir])dnl
|
||||
# end of AC_DEFUN of LIBOPTS_CHECK
|
||||
])
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# liboptschk.m4 serial 2 (autogen - 5.11.4)
|
||||
dnl Copyright (c) 2005-2012 by Bruce Korb - all rights reserved
|
||||
dnl
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
dnl
|
||||
dnl Time-stamp: "2010-12-07 12:57:56 bkorb"
|
||||
dnl
|
||||
AC_DEFUN([ag_FIND_LIBOPTS],
|
||||
[if test "X${ac_cv_header_autoopts_options_h}" = Xno
|
||||
then :
|
||||
else
|
||||
f=`autoopts-config cflags` 2>/dev/null
|
||||
if test X"${f}" = X
|
||||
then
|
||||
:
|
||||
else
|
||||
AC_DEFINE([HAVE_LIBOPTS],[1],[define if we can find libopts])
|
||||
CFLAGS="${CFLAGS} ${f}"
|
||||
ao_CFLAGS="${f}"
|
||||
AC_SUBST(ao_CFLAGS)
|
||||
|
||||
f=`autoopts-config ldflags` 2>/dev/null
|
||||
LIBS="${LIBS} ${f}"
|
||||
ao_LIBS="${f}"
|
||||
AC_SUBST(ao_LIBS)
|
||||
fi
|
||||
fi])
|
||||
@@ -0,0 +1,838 @@
|
||||
|
||||
/**
|
||||
* \file makeshell.c
|
||||
*
|
||||
* Time-stamp: "2012-04-07 09:03:16 bkorb"
|
||||
*
|
||||
* This module will interpret the options set in the tOptions
|
||||
* structure and create a Bourne shell script capable of parsing them.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
tOptions * optionParseShellOptions = NULL;
|
||||
|
||||
static char const * shell_prog = NULL;
|
||||
static char * script_leader = NULL;
|
||||
static char * script_trailer = NULL;
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static void
|
||||
emit_var_text(char const * prog, char const * var, int fdin);
|
||||
|
||||
static void
|
||||
text_to_var(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
emit_usage(tOptions * pOpts);
|
||||
|
||||
static void
|
||||
emit_setup(tOptions * pOpts);
|
||||
|
||||
static void
|
||||
emit_action(tOptions * pOpts, tOptDesc* pOptDesc);
|
||||
|
||||
static void
|
||||
emit_inaction(tOptions * pOpts, tOptDesc* pOptDesc);
|
||||
|
||||
static void
|
||||
emit_flag(tOptions * pOpts);
|
||||
|
||||
static void
|
||||
emit_match_expr(char const * pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts);
|
||||
|
||||
static void
|
||||
emitLong(tOptions * pOpts);
|
||||
|
||||
static void
|
||||
open_out(char const * pzFile);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/*=export_func optionParseShell
|
||||
* private:
|
||||
*
|
||||
* what: Decipher a boolean value
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
*
|
||||
* doc:
|
||||
* Emit a shell script that will parse the command line options.
|
||||
=*/
|
||||
void
|
||||
optionParseShell(tOptions * pOpts)
|
||||
{
|
||||
/*
|
||||
* Check for our SHELL option now.
|
||||
* IF the output file contains the "#!" magic marker,
|
||||
* it will override anything we do here.
|
||||
*/
|
||||
if (HAVE_GENSHELL_OPT(SHELL))
|
||||
shell_prog = GENSHELL_OPT_ARG(SHELL);
|
||||
|
||||
else if (! ENABLED_GENSHELL_OPT(SHELL))
|
||||
shell_prog = NULL;
|
||||
|
||||
else if ((shell_prog = getenv("SHELL")),
|
||||
shell_prog == NULL)
|
||||
|
||||
shell_prog = POSIX_SHELL;
|
||||
|
||||
/*
|
||||
* Check for a specified output file
|
||||
*/
|
||||
if (HAVE_GENSHELL_OPT(SCRIPT))
|
||||
open_out(GENSHELL_OPT_ARG(SCRIPT));
|
||||
|
||||
emit_usage(pOpts);
|
||||
emit_setup(pOpts);
|
||||
|
||||
/*
|
||||
* There are four modes of option processing.
|
||||
*/
|
||||
switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) {
|
||||
case OPTPROC_LONGOPT:
|
||||
fputs(LOOP_STR, stdout);
|
||||
|
||||
fputs(LONG_OPT_MARK, stdout);
|
||||
fputs(INIT_LOPT_STR, stdout);
|
||||
emitLong(pOpts);
|
||||
printf(LOPT_ARG_FMT, pOpts->pzPROGNAME);
|
||||
fputs(END_OPT_SEL_STR, stdout);
|
||||
|
||||
fputs(NOT_FOUND_STR, stdout);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
fputs(ONLY_OPTS_LOOP, stdout);
|
||||
fputs(INIT_LOPT_STR, stdout);
|
||||
emitLong(pOpts);
|
||||
printf(LOPT_ARG_FMT, pOpts->pzPROGNAME);
|
||||
break;
|
||||
|
||||
case OPTPROC_SHORTOPT:
|
||||
fputs(LOOP_STR, stdout);
|
||||
|
||||
fputs(FLAG_OPT_MARK, stdout);
|
||||
fputs(INIT_OPT_STR, stdout);
|
||||
emit_flag(pOpts);
|
||||
printf(OPT_ARG_FMT, pOpts->pzPROGNAME);
|
||||
fputs(END_OPT_SEL_STR, stdout);
|
||||
|
||||
fputs(NOT_FOUND_STR, stdout);
|
||||
break;
|
||||
|
||||
case OPTPROC_LONGOPT|OPTPROC_SHORTOPT:
|
||||
fputs(LOOP_STR, stdout);
|
||||
|
||||
fputs(LONG_OPT_MARK, stdout);
|
||||
fputs(INIT_LOPT_STR, stdout);
|
||||
emitLong(pOpts);
|
||||
printf(LOPT_ARG_FMT, pOpts->pzPROGNAME);
|
||||
fputs(END_OPT_SEL_STR, stdout);
|
||||
|
||||
fputs(FLAG_OPT_MARK, stdout);
|
||||
fputs(INIT_OPT_STR, stdout);
|
||||
emit_flag(pOpts);
|
||||
printf(OPT_ARG_FMT, pOpts->pzPROGNAME);
|
||||
fputs(END_OPT_SEL_STR, stdout);
|
||||
|
||||
fputs(NOT_FOUND_STR, stdout);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(zLoopEnd, pOpts->pzPROGNAME, END_MARK);
|
||||
if ((script_trailer != NULL) && (*script_trailer != NUL))
|
||||
fputs(script_trailer, stdout);
|
||||
else if (ENABLED_GENSHELL_OPT(SHELL))
|
||||
printf(SHOW_PROG_ENV, pOpts->pzPROGNAME);
|
||||
|
||||
#ifdef HAVE_FCHMOD
|
||||
fchmod(STDOUT_FILENO, 0755);
|
||||
#endif
|
||||
fclose(stdout);
|
||||
|
||||
if (ferror(stdout)) {
|
||||
fputs(zOutputFail, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
static void
|
||||
emit_var_text(char const * prog, char const * var, int fdin)
|
||||
{
|
||||
FILE * fp = fdopen(fdin, "r" FOPEN_BINARY_FLAG);
|
||||
int nlct = 0; /* defer newlines and skip trailing ones */
|
||||
|
||||
printf(SET_TEXT_FMT, prog, var);
|
||||
if (fp == NULL)
|
||||
goto skip_text;
|
||||
|
||||
for (;;) {
|
||||
int ch = fgetc(fp);
|
||||
switch (ch) {
|
||||
|
||||
case NL:
|
||||
nlct++;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
while (nlct > 0) {
|
||||
fputc(NL, stdout);
|
||||
nlct--;
|
||||
}
|
||||
fputs(apostrophy, stdout);
|
||||
break;
|
||||
|
||||
case EOF:
|
||||
goto endCharLoop;
|
||||
|
||||
default:
|
||||
while (nlct > 0) {
|
||||
fputc(NL, stdout);
|
||||
nlct--;
|
||||
}
|
||||
fputc(ch, stdout);
|
||||
break;
|
||||
}
|
||||
} endCharLoop:;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
skip_text:
|
||||
|
||||
fputs(END_SET_TEXT, stdout);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The purpose of this function is to assign "long usage", short usage
|
||||
* and version information to a shell variable. Rather than wind our
|
||||
* way through all the logic necessary to emit the text directly, we
|
||||
* fork(), have our child process emit the text the normal way and
|
||||
* capture the output in the parent process.
|
||||
*/
|
||||
static void
|
||||
text_to_var(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD)
|
||||
{
|
||||
# define _TT_(n) static char const z ## n [] = #n;
|
||||
TEXTTO_TABLE
|
||||
# undef _TT_
|
||||
# define _TT_(n) z ## n ,
|
||||
static char const * apzTTNames[] = { TEXTTO_TABLE };
|
||||
# undef _TT_
|
||||
|
||||
#if ! defined(HAVE_WORKING_FORK)
|
||||
printf(SET_NO_TEXT_FMT, pOpts->pzPROGNAME, apzTTNames[ whichVar]);
|
||||
#else
|
||||
int pipeFd[2];
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
if (pipe(pipeFd) != 0) {
|
||||
fprintf(stderr, zBadPipe, errno, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
fprintf(stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/*
|
||||
* Send both stderr and stdout to the pipe. No matter which
|
||||
* descriptor is used, we capture the output on the read end.
|
||||
*/
|
||||
dup2(pipeFd[1], STDERR_FILENO);
|
||||
dup2(pipeFd[1], STDOUT_FILENO);
|
||||
close(pipeFd[0]);
|
||||
|
||||
switch (whichVar) {
|
||||
case TT_LONGUSAGE:
|
||||
(*(pOpts->pUsageProc))(pOpts, EXIT_SUCCESS);
|
||||
/* NOTREACHED */
|
||||
|
||||
case TT_USAGE:
|
||||
(*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
|
||||
case TT_VERSION:
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
pOD->optArg.argString = "c";
|
||||
optionPrintVersion(pOpts, pOD);
|
||||
/* NOTREACHED */
|
||||
|
||||
default:
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
default:
|
||||
close(pipeFd[1]);
|
||||
}
|
||||
|
||||
emit_var_text(pOpts->pzPROGNAME, apzTTNames[whichVar], pipeFd[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
emit_usage(tOptions * pOpts)
|
||||
{
|
||||
char zTimeBuf[AO_NAME_SIZE];
|
||||
|
||||
/*
|
||||
* First, switch stdout to the output file name.
|
||||
* Then, change the program name to the one defined
|
||||
* by the definitions (rather than the current
|
||||
* executable name). Down case the upper cased name.
|
||||
*/
|
||||
if (script_leader != NULL)
|
||||
fputs(script_leader, stdout);
|
||||
|
||||
{
|
||||
char const * out_nm;
|
||||
|
||||
{
|
||||
time_t c_tim = time(NULL);
|
||||
struct tm * ptm = localtime(&c_tim);
|
||||
strftime(zTimeBuf, AO_NAME_SIZE, TIME_FMT, ptm );
|
||||
}
|
||||
|
||||
if (HAVE_GENSHELL_OPT(SCRIPT))
|
||||
out_nm = GENSHELL_OPT_ARG(SCRIPT);
|
||||
else out_nm = STDOUT;
|
||||
|
||||
if ((script_leader == NULL) && (shell_prog != NULL))
|
||||
printf(SHELL_MAGIC, shell_prog);
|
||||
|
||||
printf(PREAMBLE_FMT, START_MARK, out_nm, zTimeBuf);
|
||||
}
|
||||
|
||||
printf(END_PRE_FMT, pOpts->pzPROGNAME);
|
||||
|
||||
/*
|
||||
* Get a copy of the original program name in lower case and
|
||||
* fill in an approximation of the program name from it.
|
||||
*/
|
||||
{
|
||||
char * pzPN = zTimeBuf;
|
||||
char const * pz = pOpts->pzPROGNAME;
|
||||
char ** pp;
|
||||
|
||||
for (;;) {
|
||||
if ((*pzPN++ = (char)tolower(*pz++)) == NUL)
|
||||
break;
|
||||
}
|
||||
|
||||
pp = (char **)(void *)&(pOpts->pzProgPath);
|
||||
*pp = zTimeBuf;
|
||||
pp = (char **)(void *)&(pOpts->pzProgName);
|
||||
*pp = zTimeBuf;
|
||||
}
|
||||
|
||||
text_to_var(pOpts, TT_LONGUSAGE, NULL);
|
||||
text_to_var(pOpts, TT_USAGE, NULL);
|
||||
|
||||
{
|
||||
tOptDesc* pOptDesc = pOpts->pOptDesc;
|
||||
int optionCt = pOpts->optCt;
|
||||
|
||||
for (;;) {
|
||||
if (pOptDesc->pOptProc == optionPrintVersion) {
|
||||
text_to_var(pOpts, TT_VERSION, pOptDesc);
|
||||
break;
|
||||
}
|
||||
|
||||
if (--optionCt <= 0)
|
||||
break;
|
||||
pOptDesc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
emit_setup(tOptions * pOpts)
|
||||
{
|
||||
tOptDesc * pOptDesc = pOpts->pOptDesc;
|
||||
int optionCt = pOpts->presetOptCt;
|
||||
char const * pzFmt;
|
||||
char const * pzDefault;
|
||||
|
||||
for (;optionCt > 0; pOptDesc++, --optionCt) {
|
||||
char zVal[32];
|
||||
|
||||
/*
|
||||
* Options that are either usage documentation or are compiled out
|
||||
* are not to be processed.
|
||||
*/
|
||||
if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL))
|
||||
continue;
|
||||
|
||||
if (pOptDesc->optMaxCt > 1)
|
||||
pzFmt = MULTI_DEF_FMT;
|
||||
else pzFmt = SGL_DEF_FMT;
|
||||
|
||||
/*
|
||||
* IF this is an enumeration/bitmask option, then convert the value
|
||||
* to a string before printing the default value.
|
||||
*/
|
||||
switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) {
|
||||
case OPARG_TYPE_ENUMERATION:
|
||||
(*(pOptDesc->pOptProc))(OPTPROC_EMIT_SHELL, pOptDesc );
|
||||
pzDefault = pOptDesc->optArg.argString;
|
||||
break;
|
||||
|
||||
/*
|
||||
* Numeric and membership bit options are just printed as a number.
|
||||
*/
|
||||
case OPARG_TYPE_NUMERIC:
|
||||
snprintf(zVal, sizeof(zVal), "%d",
|
||||
(int)pOptDesc->optArg.argInt);
|
||||
pzDefault = zVal;
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_MEMBERSHIP:
|
||||
snprintf(zVal, sizeof(zVal), "%lu",
|
||||
(unsigned long)pOptDesc->optArg.argIntptr);
|
||||
pzDefault = zVal;
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_BOOLEAN:
|
||||
pzDefault = (pOptDesc->optArg.argBool) ? TRUE_STR : FALSE_STR;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pOptDesc->optArg.argString == NULL) {
|
||||
if (pzFmt == SGL_DEF_FMT)
|
||||
pzFmt = SGL_NO_DEF_FMT;
|
||||
pzDefault = NULL;
|
||||
}
|
||||
else
|
||||
pzDefault = pOptDesc->optArg.argString;
|
||||
}
|
||||
|
||||
printf(pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_action(tOptions * pOpts, tOptDesc* pOptDesc)
|
||||
{
|
||||
if (pOptDesc->pOptProc == optionPrintVersion)
|
||||
printf(zTextExit, pOpts->pzPROGNAME, VER_STR);
|
||||
|
||||
else if (pOptDesc->pOptProc == optionPagedUsage)
|
||||
printf(zPagedUsageExit, pOpts->pzPROGNAME);
|
||||
|
||||
else if (pOptDesc->pOptProc == optionLoadOpt) {
|
||||
printf(zCmdFmt, NO_LOAD_WARN);
|
||||
printf(zCmdFmt, YES_NEED_OPT_ARG);
|
||||
|
||||
} else if (pOptDesc->pz_NAME == NULL) {
|
||||
|
||||
if (pOptDesc->pOptProc == NULL) {
|
||||
printf(zCmdFmt, NO_SAVE_OPTS);
|
||||
printf(zCmdFmt, OK_NEED_OPT_ARG);
|
||||
} else
|
||||
printf(zTextExit, pOpts->pzPROGNAME, LONG_USE_STR);
|
||||
|
||||
} else {
|
||||
if (pOptDesc->optMaxCt == 1)
|
||||
printf(SGL_ARG_FMT, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
|
||||
else {
|
||||
if ((unsigned)pOptDesc->optMaxCt < NOLIMIT)
|
||||
printf(zCountTest, pOpts->pzPROGNAME,
|
||||
pOptDesc->pz_NAME, pOptDesc->optMaxCt);
|
||||
|
||||
printf(MULTI_ARG_FMT, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix up the args.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) {
|
||||
printf(zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
|
||||
|
||||
} else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) {
|
||||
printf(zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
|
||||
|
||||
} else {
|
||||
fputs(zMustArg, stdout);
|
||||
}
|
||||
}
|
||||
fputs(zOptionEndSelect, stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
emit_inaction(tOptions * pOpts, tOptDesc* pOptDesc)
|
||||
{
|
||||
if (pOptDesc->pOptProc == optionLoadOpt) {
|
||||
printf(zCmdFmt, NO_SUPPRESS_LOAD);
|
||||
|
||||
} else if (pOptDesc->optMaxCt == 1)
|
||||
printf(NO_SGL_ARG_FMT, pOpts->pzPROGNAME,
|
||||
pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx);
|
||||
else
|
||||
printf(NO_MULTI_ARG_FMT, pOpts->pzPROGNAME,
|
||||
pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx);
|
||||
|
||||
printf(zCmdFmt, NO_ARG_NEEDED);
|
||||
fputs(zOptionEndSelect, stdout);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
emit_flag(tOptions * pOpts)
|
||||
{
|
||||
tOptDesc* pOptDesc = pOpts->pOptDesc;
|
||||
int optionCt = pOpts->optCt;
|
||||
|
||||
fputs(zOptionCase, stdout);
|
||||
|
||||
for (;optionCt > 0; pOptDesc++, --optionCt) {
|
||||
|
||||
if (SKIP_OPT(pOptDesc))
|
||||
continue;
|
||||
|
||||
if (IS_GRAPHIC_CHAR(pOptDesc->optValue)) {
|
||||
printf(zOptionFlag, pOptDesc->optValue);
|
||||
emit_action(pOpts, pOptDesc);
|
||||
}
|
||||
}
|
||||
printf(UNK_OPT_FMT, FLAG_STR, pOpts->pzPROGNAME);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit the match text for a long option
|
||||
*/
|
||||
static void
|
||||
emit_match_expr(char const * pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts)
|
||||
{
|
||||
tOptDesc* pOD = pOpts->pOptDesc;
|
||||
int oCt = pOpts->optCt;
|
||||
int min = 1;
|
||||
char zName[ 256 ];
|
||||
char* pz = zName;
|
||||
|
||||
for (;;) {
|
||||
int matchCt = 0;
|
||||
|
||||
/*
|
||||
* Omit the current option, Documentation opts and compiled out opts.
|
||||
*/
|
||||
if ((pOD == pCurOpt) || SKIP_OPT(pOD)){
|
||||
if (--oCt <= 0)
|
||||
break;
|
||||
pOD++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check each character of the name case insensitively.
|
||||
* They must not be the same. They cannot be, because it would
|
||||
* not compile correctly if they were.
|
||||
*/
|
||||
while ( toupper(pOD->pz_Name[matchCt])
|
||||
== toupper(pzMatchName[matchCt]))
|
||||
matchCt++;
|
||||
|
||||
if (matchCt > min)
|
||||
min = matchCt;
|
||||
|
||||
/*
|
||||
* Check the disablement name, too.
|
||||
*/
|
||||
if (pOD->pz_DisableName != NULL) {
|
||||
matchCt = 0;
|
||||
while ( toupper(pOD->pz_DisableName[matchCt])
|
||||
== toupper(pzMatchName[matchCt]))
|
||||
matchCt++;
|
||||
if (matchCt > min)
|
||||
min = matchCt;
|
||||
}
|
||||
if (--oCt <= 0)
|
||||
break;
|
||||
pOD++;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF the 'min' is all or one short of the name length,
|
||||
* THEN the entire string must be matched.
|
||||
*/
|
||||
if ( (pzMatchName[min ] == NUL)
|
||||
|| (pzMatchName[min+1] == NUL) )
|
||||
printf(zOptionFullName, pzMatchName);
|
||||
|
||||
else {
|
||||
int matchCt = 0;
|
||||
for (; matchCt <= min; matchCt++)
|
||||
*pz++ = pzMatchName[matchCt];
|
||||
|
||||
for (;;) {
|
||||
*pz = NUL;
|
||||
printf(zOptionPartName, zName);
|
||||
*pz++ = pzMatchName[matchCt++];
|
||||
if (pzMatchName[matchCt] == NUL) {
|
||||
*pz = NUL;
|
||||
printf(zOptionFullName, zName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Emit GNU-standard long option handling code
|
||||
*/
|
||||
static void
|
||||
emitLong(tOptions * pOpts)
|
||||
{
|
||||
tOptDesc* pOD = pOpts->pOptDesc;
|
||||
int ct = pOpts->optCt;
|
||||
|
||||
fputs(zOptionCase, stdout);
|
||||
|
||||
/*
|
||||
* do each option, ...
|
||||
*/
|
||||
do {
|
||||
/*
|
||||
* Documentation & compiled-out options
|
||||
*/
|
||||
if (SKIP_OPT(pOD))
|
||||
continue;
|
||||
|
||||
emit_match_expr(pOD->pz_Name, pOD, pOpts);
|
||||
emit_action(pOpts, pOD);
|
||||
|
||||
/*
|
||||
* Now, do the same thing for the disablement version of the option.
|
||||
*/
|
||||
if (pOD->pz_DisableName != NULL) {
|
||||
emit_match_expr(pOD->pz_DisableName, pOD, pOpts);
|
||||
emit_inaction(pOpts, pOD);
|
||||
}
|
||||
} while (pOD++, --ct > 0);
|
||||
|
||||
printf(UNK_OPT_FMT, OPTION_STR, pOpts->pzPROGNAME);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
open_out(char const * pzFile)
|
||||
{
|
||||
FILE* fp;
|
||||
char* pzData = NULL;
|
||||
struct stat stbf;
|
||||
|
||||
do {
|
||||
char* pzScan;
|
||||
size_t sizeLeft;
|
||||
|
||||
/*
|
||||
* IF we cannot stat the file,
|
||||
* THEN assume we are creating a new file.
|
||||
* Skip the loading of the old data.
|
||||
*/
|
||||
if (stat(pzFile, &stbf) != 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
* The file must be a regular file
|
||||
*/
|
||||
if (! S_ISREG(stbf.st_mode)) {
|
||||
fprintf(stderr, zNotFile, pzFile);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pzData = AGALOC(stbf.st_size + 1, "f data");
|
||||
fp = fopen(pzFile, "r" FOPEN_BINARY_FLAG);
|
||||
|
||||
sizeLeft = (unsigned)stbf.st_size;
|
||||
pzScan = pzData;
|
||||
|
||||
/*
|
||||
* Read in all the data as fast as our OS will let us.
|
||||
*/
|
||||
for (;;) {
|
||||
int inct = fread((void*)pzScan, (size_t)1, sizeLeft, fp);
|
||||
if (inct == 0)
|
||||
break;
|
||||
|
||||
pzScan += inct;
|
||||
sizeLeft -= inct;
|
||||
|
||||
if (sizeLeft == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* NUL-terminate the leader and look for the trailer
|
||||
*/
|
||||
*pzScan = NUL;
|
||||
fclose(fp);
|
||||
pzScan = strstr(pzData, START_MARK);
|
||||
if (pzScan == NULL) {
|
||||
script_trailer = pzData;
|
||||
break;
|
||||
}
|
||||
|
||||
*(pzScan++) = NUL;
|
||||
pzScan = strstr(pzScan, END_MARK);
|
||||
if (pzScan == NULL) {
|
||||
script_trailer = pzData;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if the data contains our marker.
|
||||
* If it does, then we will skip over it
|
||||
*/
|
||||
script_trailer = pzScan + END_MARK_LEN;
|
||||
script_leader = pzData;
|
||||
} while (false);
|
||||
|
||||
if (freopen(pzFile, "w" FOPEN_BINARY_FLAG, stdout) != stdout) {
|
||||
fprintf(stderr, zFreopenFail, errno, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func genshelloptUsage
|
||||
* private:
|
||||
* what: The usage function for the genshellopt generated program
|
||||
*
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + int + exitCode + usage text type to produce +
|
||||
*
|
||||
* doc:
|
||||
* This function is used to create the usage strings for the option
|
||||
* processing shell script code. Two child processes are spawned
|
||||
* each emitting the usage text in either the short (error exit)
|
||||
* style or the long style. The generated program will capture this
|
||||
* and create shell script variables containing the two types of text.
|
||||
=*/
|
||||
void
|
||||
genshelloptUsage(tOptions * pOpts, int exitCode)
|
||||
{
|
||||
#if ! defined(HAVE_WORKING_FORK)
|
||||
optionUsage(pOpts, exitCode);
|
||||
#else
|
||||
/*
|
||||
* IF not EXIT_SUCCESS,
|
||||
* THEN emit the short form of usage.
|
||||
*/
|
||||
if (exitCode != EXIT_SUCCESS)
|
||||
optionUsage(pOpts, exitCode);
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
if (ferror(stdout) || ferror(stderr))
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
option_usage_fp = stdout;
|
||||
|
||||
/*
|
||||
* First, print our usage
|
||||
*/
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
optionUsage(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
|
||||
case 0:
|
||||
pagerState = PAGER_STATE_CHILD;
|
||||
optionUsage(pOpts, EXIT_SUCCESS);
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
default:
|
||||
{
|
||||
int sts;
|
||||
wait(&sts);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate the pzProgName, since optionProcess() normally
|
||||
* gets it from the command line
|
||||
*/
|
||||
{
|
||||
char * pz;
|
||||
char ** pp = (char **)(void *)&(optionParseShellOptions->pzProgName);
|
||||
AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "prog name");
|
||||
*pp = pz;
|
||||
while (*pz != NUL) {
|
||||
*pz = tolower(*pz);
|
||||
pz++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Separate the makeshell usage from the client usage
|
||||
*/
|
||||
fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName);
|
||||
fflush(option_usage_fp);
|
||||
|
||||
/*
|
||||
* Now, print the client usage.
|
||||
*/
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
pagerState = PAGER_STATE_CHILD;
|
||||
/*FALLTHROUGH*/
|
||||
case -1:
|
||||
optionUsage(optionParseShellOptions, EXIT_FAILURE);
|
||||
|
||||
default:
|
||||
{
|
||||
int sts;
|
||||
wait(&sts);
|
||||
}
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
if (ferror(stdout)) {
|
||||
fputs(zOutputFail, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/makeshell.c */
|
||||
@@ -0,0 +1,849 @@
|
||||
|
||||
/**
|
||||
* \file nested.c
|
||||
*
|
||||
* Time-stamp: "2012-03-04 13:30:07 bkorb"
|
||||
*
|
||||
* Automated Options Nested Values module.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int xml_ch;
|
||||
int xml_len;
|
||||
char xml_txt[8];
|
||||
} xml_xlate_t;
|
||||
|
||||
static xml_xlate_t const xml_xlate[] = {
|
||||
{ '&', 4, "amp;" },
|
||||
{ '<', 3, "lt;" },
|
||||
{ '>', 3, "gt;" },
|
||||
{ '"', 5, "quot;" },
|
||||
{ '\'',5, "apos;" }
|
||||
};
|
||||
|
||||
#ifndef ENOMSG
|
||||
#define ENOMSG ENOENT
|
||||
#endif
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static void
|
||||
remove_continuation(char* pzSrc);
|
||||
|
||||
static char const*
|
||||
scan_q_str(char const* pzTxt);
|
||||
|
||||
static tOptionValue *
|
||||
add_string(void ** pp, char const * pzName, size_t nameLen,
|
||||
char const* pzValue, size_t dataLen);
|
||||
|
||||
static tOptionValue *
|
||||
add_bool(void ** pp, char const * pzName, size_t nameLen,
|
||||
char const* pzValue, size_t dataLen);
|
||||
|
||||
static tOptionValue*
|
||||
add_number(void** pp, char const* pzName, size_t nameLen,
|
||||
char const* pzValue, size_t dataLen);
|
||||
|
||||
static tOptionValue*
|
||||
add_nested(void** pp, char const* pzName, size_t nameLen,
|
||||
char* pzValue, size_t dataLen);
|
||||
|
||||
static char const *
|
||||
scan_name(char const* pzName, tOptionValue* pRes);
|
||||
|
||||
static char const*
|
||||
scan_xml(char const* pzName, tOptionValue* pRes);
|
||||
|
||||
static void
|
||||
sort_list(tArgList* pAL);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/**
|
||||
* Backslashes are used for line continuations. We keep the newline
|
||||
* characters, but trim out the backslash:
|
||||
*/
|
||||
static void
|
||||
remove_continuation(char* pzSrc)
|
||||
{
|
||||
char* pzD;
|
||||
|
||||
do {
|
||||
while (*pzSrc == NL) pzSrc++;
|
||||
pzD = strchr(pzSrc, NL);
|
||||
if (pzD == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* pzD has skipped at least one non-newline character and now
|
||||
* points to a newline character. It now becomes the source and
|
||||
* pzD goes to the previous character.
|
||||
*/
|
||||
pzSrc = pzD--;
|
||||
if (*pzD != '\\')
|
||||
pzD++;
|
||||
} while (pzD == pzSrc);
|
||||
|
||||
/*
|
||||
* Start shifting text.
|
||||
*/
|
||||
for (;;) {
|
||||
char ch = ((*pzD++) = *(pzSrc++));
|
||||
switch (ch) {
|
||||
case NUL: return;
|
||||
case '\\':
|
||||
if (*pzSrc == NL)
|
||||
--pzD; /* rewrite on next iteration */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the end of a quoted string, skipping escaped quote characters.
|
||||
*/
|
||||
static char const*
|
||||
scan_q_str(char const* pzTxt)
|
||||
{
|
||||
char q = *(pzTxt++); /* remember the type of quote */
|
||||
|
||||
for (;;) {
|
||||
char ch = *(pzTxt++);
|
||||
if (ch == NUL)
|
||||
return pzTxt-1;
|
||||
|
||||
if (ch == q)
|
||||
return pzTxt;
|
||||
|
||||
if (ch == '\\') {
|
||||
ch = *(pzTxt++);
|
||||
/*
|
||||
* IF the next character is NUL, drop the backslash, too.
|
||||
*/
|
||||
if (ch == NUL)
|
||||
return pzTxt - 2;
|
||||
|
||||
/*
|
||||
* IF the quote character or the escape character were escaped,
|
||||
* then skip both, as long as the string does not end.
|
||||
*/
|
||||
if ((ch == q) || (ch == '\\')) {
|
||||
if (*(pzTxt++) == NUL)
|
||||
return pzTxt-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Associate a name with either a string or no value.
|
||||
*/
|
||||
static tOptionValue *
|
||||
add_string(void ** pp, char const * pzName, size_t nameLen,
|
||||
char const* pzValue, size_t dataLen)
|
||||
{
|
||||
tOptionValue* pNV;
|
||||
size_t sz = nameLen + dataLen + sizeof(*pNV);
|
||||
|
||||
pNV = AGALOC(sz, "option name/str value pair");
|
||||
if (pNV == NULL)
|
||||
return NULL;
|
||||
|
||||
if (pzValue == NULL) {
|
||||
pNV->valType = OPARG_TYPE_NONE;
|
||||
pNV->pzName = pNV->v.strVal;
|
||||
|
||||
} else {
|
||||
pNV->valType = OPARG_TYPE_STRING;
|
||||
if (dataLen > 0) {
|
||||
char const * pzSrc = pzValue;
|
||||
char * pzDst = pNV->v.strVal;
|
||||
int ct = dataLen;
|
||||
do {
|
||||
int ch = *(pzSrc++) & 0xFF;
|
||||
if (ch == NUL) goto data_copy_done;
|
||||
if (ch == '&')
|
||||
ch = get_special_char(&pzSrc, &ct);
|
||||
*(pzDst++) = (char)ch;
|
||||
} while (--ct > 0);
|
||||
data_copy_done:
|
||||
*pzDst = NUL;
|
||||
|
||||
} else {
|
||||
pNV->v.strVal[0] = NUL;
|
||||
}
|
||||
|
||||
pNV->pzName = pNV->v.strVal + dataLen + 1;
|
||||
}
|
||||
|
||||
memcpy(pNV->pzName, pzName, nameLen);
|
||||
pNV->pzName[ nameLen ] = NUL;
|
||||
addArgListEntry(pp, pNV);
|
||||
return pNV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a name with either a string or no value.
|
||||
*/
|
||||
static tOptionValue *
|
||||
add_bool(void ** pp, char const * pzName, size_t nameLen,
|
||||
char const* pzValue, size_t dataLen)
|
||||
{
|
||||
tOptionValue * pNV;
|
||||
|
||||
{
|
||||
size_t sz = nameLen + sizeof(tOptionValue) + 1;
|
||||
pNV = AGALOC(sz, "name/bool value");
|
||||
}
|
||||
|
||||
{
|
||||
char * p = SPN_WHITESPACE_CHARS(pzValue);
|
||||
dataLen -= p - pzValue;
|
||||
pzValue = p;
|
||||
}
|
||||
|
||||
if (dataLen == 0)
|
||||
pNV->v.boolVal = 0;
|
||||
|
||||
else if (IS_DEC_DIGIT_CHAR(*pzValue))
|
||||
pNV->v.boolVal = atoi(pzValue);
|
||||
|
||||
else pNV->v.boolVal = ! IS_FALSE_TYPE_CHAR(*pzValue);
|
||||
|
||||
pNV->valType = OPARG_TYPE_BOOLEAN;
|
||||
pNV->pzName = (char*)(pNV + 1);
|
||||
memcpy(pNV->pzName, pzName, nameLen);
|
||||
pNV->pzName[ nameLen ] = NUL;
|
||||
addArgListEntry(pp, pNV);
|
||||
return pNV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a name with either a string or no value.
|
||||
*/
|
||||
static tOptionValue*
|
||||
add_number(void** pp, char const* pzName, size_t nameLen,
|
||||
char const* pzValue, size_t dataLen)
|
||||
{
|
||||
tOptionValue* pNV;
|
||||
size_t sz = nameLen + sizeof(*pNV) + 1;
|
||||
|
||||
pNV = AGALOC(sz, "option name/bool value pair");
|
||||
if (pNV == NULL)
|
||||
return NULL;
|
||||
while (IS_WHITESPACE_CHAR(*pzValue) && (dataLen > 0)) {
|
||||
dataLen--; pzValue++;
|
||||
}
|
||||
if (dataLen == 0)
|
||||
pNV->v.longVal = 0;
|
||||
else
|
||||
pNV->v.longVal = strtol(pzValue, 0, 0);
|
||||
|
||||
pNV->valType = OPARG_TYPE_NUMERIC;
|
||||
pNV->pzName = (char*)(pNV + 1);
|
||||
memcpy(pNV->pzName, pzName, nameLen);
|
||||
pNV->pzName[ nameLen ] = NUL;
|
||||
addArgListEntry(pp, pNV);
|
||||
return pNV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate a name with either a string or no value.
|
||||
*/
|
||||
static tOptionValue*
|
||||
add_nested(void** pp, char const* pzName, size_t nameLen,
|
||||
char* pzValue, size_t dataLen)
|
||||
{
|
||||
tOptionValue* pNV;
|
||||
|
||||
if (dataLen == 0) {
|
||||
size_t sz = nameLen + sizeof(*pNV) + 1;
|
||||
pNV = AGALOC(sz, "empty nested value pair");
|
||||
if (pNV == NULL)
|
||||
return NULL;
|
||||
pNV->v.nestVal = NULL;
|
||||
pNV->valType = OPARG_TYPE_HIERARCHY;
|
||||
pNV->pzName = (char*)(pNV + 1);
|
||||
memcpy(pNV->pzName, pzName, nameLen);
|
||||
pNV->pzName[ nameLen ] = NUL;
|
||||
|
||||
} else {
|
||||
pNV = optionLoadNested(pzValue, pzName, nameLen);
|
||||
}
|
||||
|
||||
if (pNV != NULL)
|
||||
addArgListEntry(pp, pNV);
|
||||
|
||||
return pNV;
|
||||
}
|
||||
|
||||
/**
|
||||
* We have an entry that starts with a name. Find the end of it, cook it
|
||||
* (if called for) and create the name/value association.
|
||||
*/
|
||||
static char const *
|
||||
scan_name(char const* pzName, tOptionValue* pRes)
|
||||
{
|
||||
tOptionValue* pNV;
|
||||
char const * pzScan = pzName+1; /* we know first char is a name char */
|
||||
char const * pzVal;
|
||||
size_t nameLen = 1;
|
||||
size_t dataLen = 0;
|
||||
|
||||
/*
|
||||
* Scan over characters that name a value. These names may not end
|
||||
* with a colon, but they may contain colons.
|
||||
*/
|
||||
pzScan = SPN_VALUE_NAME_CHARS(pzName + 1);
|
||||
if (pzScan[-1] == ':')
|
||||
pzScan--;
|
||||
nameLen = pzScan - pzName;
|
||||
|
||||
pzScan = SPN_HORIZ_WHITE_CHARS(pzScan);
|
||||
|
||||
re_switch:
|
||||
|
||||
switch (*pzScan) {
|
||||
case '=':
|
||||
case ':':
|
||||
pzScan = SPN_HORIZ_WHITE_CHARS(pzScan + 1);
|
||||
if ((*pzScan == '=') || (*pzScan == ':'))
|
||||
goto default_char;
|
||||
goto re_switch;
|
||||
|
||||
case NL:
|
||||
case ',':
|
||||
pzScan++;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case NUL:
|
||||
add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
|
||||
break;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
pzVal = pzScan;
|
||||
pzScan = scan_q_str(pzScan);
|
||||
dataLen = pzScan - pzVal;
|
||||
pNV = add_string(&(pRes->v.nestVal), pzName, nameLen, pzVal,
|
||||
dataLen);
|
||||
if ((pNV != NULL) && (option_load_mode == OPTION_LOAD_COOKED))
|
||||
ao_string_cook(pNV->v.strVal, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
default_char:
|
||||
/*
|
||||
* We have found some strange text value. It ends with a newline
|
||||
* or a comma.
|
||||
*/
|
||||
pzVal = pzScan;
|
||||
for (;;) {
|
||||
char ch = *(pzScan++);
|
||||
switch (ch) {
|
||||
case NUL:
|
||||
pzScan--;
|
||||
dataLen = pzScan - pzVal;
|
||||
goto string_done;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case NL:
|
||||
if ( (pzScan > pzVal + 2)
|
||||
&& (pzScan[-2] == '\\')
|
||||
&& (pzScan[ 0] != NUL))
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case ',':
|
||||
dataLen = (pzScan - pzVal) - 1;
|
||||
string_done:
|
||||
pNV = add_string(&(pRes->v.nestVal), pzName, nameLen,
|
||||
pzVal, dataLen);
|
||||
if (pNV != NULL)
|
||||
remove_continuation(pNV->v.strVal);
|
||||
goto leave_scan_name;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} leave_scan_name:;
|
||||
|
||||
return pzScan;
|
||||
}
|
||||
|
||||
/**
|
||||
* We've found a '<' character. We ignore this if it is a comment or a
|
||||
* directive. If it is something else, then whatever it is we are looking
|
||||
* at is bogus. Returning NULL stops processing.
|
||||
*/
|
||||
static char const*
|
||||
scan_xml(char const* pzName, tOptionValue* pRes)
|
||||
{
|
||||
size_t nameLen;
|
||||
size_t valLen;
|
||||
char const* pzScan = ++pzName;
|
||||
char const* pzVal;
|
||||
tOptionValue valu;
|
||||
tOptionValue* pNewVal;
|
||||
tOptionLoadMode save_mode = option_load_mode;
|
||||
|
||||
if (! IS_VAR_FIRST_CHAR(*pzName)) {
|
||||
switch (*pzName) {
|
||||
default:
|
||||
pzName = NULL;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
pzName = strstr(pzName, "-->");
|
||||
if (pzName != NULL)
|
||||
pzName += 3;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
pzName = strchr(pzName, '>');
|
||||
if (pzName != NULL)
|
||||
pzName++;
|
||||
break;
|
||||
}
|
||||
return pzName;
|
||||
}
|
||||
|
||||
pzScan = SPN_VALUE_NAME_CHARS(pzName+1);
|
||||
nameLen = pzScan - pzName;
|
||||
if (nameLen > 64)
|
||||
return NULL;
|
||||
valu.valType = OPARG_TYPE_STRING;
|
||||
|
||||
switch (*pzScan) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
pzScan = parse_attrs(
|
||||
NULL, (char*)pzScan, &option_load_mode, &valu );
|
||||
if (*pzScan == '>') {
|
||||
pzScan++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*pzScan != '/') {
|
||||
option_load_mode = save_mode;
|
||||
return NULL;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '/':
|
||||
if (*++pzScan != '>') {
|
||||
option_load_mode = save_mode;
|
||||
return NULL;
|
||||
}
|
||||
add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
|
||||
option_load_mode = save_mode;
|
||||
return pzScan+1;
|
||||
|
||||
default:
|
||||
option_load_mode = save_mode;
|
||||
return NULL;
|
||||
|
||||
case '>':
|
||||
pzScan++;
|
||||
break;
|
||||
}
|
||||
|
||||
pzVal = pzScan;
|
||||
|
||||
{
|
||||
char z[68];
|
||||
char* pzD = z;
|
||||
int ct = nameLen;
|
||||
char const* pzS = pzName;
|
||||
|
||||
*(pzD++) = '<';
|
||||
*(pzD++) = '/';
|
||||
|
||||
do {
|
||||
*(pzD++) = *(pzS++);
|
||||
} while (--ct > 0);
|
||||
*(pzD++) = '>';
|
||||
*pzD = NUL;
|
||||
|
||||
pzScan = strstr(pzScan, z);
|
||||
if (pzScan == NULL) {
|
||||
option_load_mode = save_mode;
|
||||
return NULL;
|
||||
}
|
||||
valLen = (pzScan - pzVal);
|
||||
pzScan += nameLen + 3;
|
||||
pzScan = SPN_WHITESPACE_CHARS(pzScan);
|
||||
}
|
||||
|
||||
switch (valu.valType) {
|
||||
case OPARG_TYPE_NONE:
|
||||
add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_STRING:
|
||||
pNewVal = add_string(
|
||||
&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen);
|
||||
|
||||
if (option_load_mode == OPTION_LOAD_KEEP)
|
||||
break;
|
||||
mungeString(pNewVal->v.strVal, option_load_mode);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_BOOLEAN:
|
||||
add_bool(&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_NUMERIC:
|
||||
add_number(&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_HIERARCHY:
|
||||
{
|
||||
char* pz = AGALOC(valLen+1, "hierarchical scan");
|
||||
if (pz == NULL)
|
||||
break;
|
||||
memcpy(pz, pzVal, valLen);
|
||||
pz[valLen] = NUL;
|
||||
add_nested(&(pRes->v.nestVal), pzName, nameLen, pz, valLen);
|
||||
AGFREE(pz);
|
||||
break;
|
||||
}
|
||||
|
||||
case OPARG_TYPE_ENUMERATION:
|
||||
case OPARG_TYPE_MEMBERSHIP:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
option_load_mode = save_mode;
|
||||
return pzScan;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deallocate a list of option arguments. This must have been gotten from
|
||||
* a hierarchical option argument, not a stacked list of strings. It is
|
||||
* an internal call, so it is not validated. The caller is responsible for
|
||||
* knowing what they are doing.
|
||||
*/
|
||||
LOCAL void
|
||||
unload_arg_list(tArgList* pAL)
|
||||
{
|
||||
int ct = pAL->useCt;
|
||||
tCC** ppNV = pAL->apzArgs;
|
||||
|
||||
while (ct-- > 0) {
|
||||
tOptionValue* pNV = (tOptionValue*)(void*)*(ppNV++);
|
||||
if (pNV->valType == OPARG_TYPE_HIERARCHY)
|
||||
unload_arg_list(pNV->v.nestVal);
|
||||
AGFREE(pNV);
|
||||
}
|
||||
|
||||
AGFREE((void*)pAL);
|
||||
}
|
||||
|
||||
/*=export_func optionUnloadNested
|
||||
*
|
||||
* what: Deallocate the memory for a nested value
|
||||
* arg: + tOptionValue const * + pOptVal + the hierarchical value +
|
||||
*
|
||||
* doc:
|
||||
* A nested value needs to be deallocated. The pointer passed in should
|
||||
* have been gotten from a call to @code{configFileLoad()} (See
|
||||
* @pxref{libopts-configFileLoad}).
|
||||
=*/
|
||||
void
|
||||
optionUnloadNested(tOptionValue const * pOV)
|
||||
{
|
||||
if (pOV == NULL) return;
|
||||
if (pOV->valType != OPARG_TYPE_HIERARCHY) {
|
||||
errno = EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
unload_arg_list(pOV->v.nestVal);
|
||||
|
||||
AGFREE((void*)pOV);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a _stable_ sort. The entries are sorted alphabetically,
|
||||
* but within entries of the same name the ordering is unchanged.
|
||||
* Typically, we also hope the input is sorted.
|
||||
*/
|
||||
static void
|
||||
sort_list(tArgList* pAL)
|
||||
{
|
||||
int ix;
|
||||
int lm = pAL->useCt;
|
||||
|
||||
/*
|
||||
* This loop iterates "useCt" - 1 times.
|
||||
*/
|
||||
for (ix = 0; ++ix < lm;) {
|
||||
int iy = ix-1;
|
||||
tOptionValue* pNewNV = (tOptionValue*)(void*)(pAL->apzArgs[ix]);
|
||||
tOptionValue* pOldNV = (tOptionValue*)(void*)(pAL->apzArgs[iy]);
|
||||
|
||||
/*
|
||||
* For as long as the new entry precedes the "old" entry,
|
||||
* move the old pointer. Stop before trying to extract the
|
||||
* "-1" entry.
|
||||
*/
|
||||
while (strcmp(pOldNV->pzName, pNewNV->pzName) > 0) {
|
||||
pAL->apzArgs[iy+1] = (void*)pOldNV;
|
||||
pOldNV = (tOptionValue*)(void*)(pAL->apzArgs[--iy]);
|
||||
if (iy < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Always store the pointer. Sometimes it is redundant,
|
||||
* but the redundancy is cheaper than a test and branch sequence.
|
||||
*/
|
||||
pAL->apzArgs[iy+1] = (void*)pNewNV;
|
||||
}
|
||||
}
|
||||
|
||||
/*=
|
||||
* private:
|
||||
*
|
||||
* what: parse a hierarchical option argument
|
||||
* arg: + char const* + pzTxt + the text to scan +
|
||||
* arg: + char const* + pzName + the name for the text +
|
||||
* arg: + size_t + nameLen + the length of "name" +
|
||||
*
|
||||
* ret_type: tOptionValue*
|
||||
* ret_desc: An allocated, compound value structure
|
||||
*
|
||||
* doc:
|
||||
* A block of text represents a series of values. It may be an
|
||||
* entire configuration file, or it may be an argument to an
|
||||
* option that takes a hierarchical value.
|
||||
*
|
||||
* If NULL is returned, errno will be set:
|
||||
* @itemize @bullet
|
||||
* @item
|
||||
* @code{EINVAL} the input text was NULL.
|
||||
* @item
|
||||
* @code{ENOMEM} the storage structures could not be allocated
|
||||
* @item
|
||||
* @code{ENOMSG} no configuration values were found
|
||||
* @end itemize
|
||||
=*/
|
||||
LOCAL tOptionValue*
|
||||
optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen)
|
||||
{
|
||||
tOptionValue* pRes;
|
||||
|
||||
/*
|
||||
* Make sure we have some data and we have space to put what we find.
|
||||
*/
|
||||
if (pzTxt == NULL) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
pzTxt = SPN_WHITESPACE_CHARS(pzTxt);
|
||||
if (*pzTxt == NUL) {
|
||||
errno = ENOMSG;
|
||||
return NULL;
|
||||
}
|
||||
pRes = AGALOC(sizeof(*pRes) + nameLen + 1, "nested args");
|
||||
if (pRes == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
pRes->valType = OPARG_TYPE_HIERARCHY;
|
||||
pRes->pzName = (char*)(pRes + 1);
|
||||
memcpy(pRes->pzName, pzName, nameLen);
|
||||
pRes->pzName[nameLen] = NUL;
|
||||
|
||||
{
|
||||
tArgList * pAL = AGALOC(sizeof(*pAL), "nested arg list");
|
||||
if (pAL == NULL) {
|
||||
AGFREE(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRes->v.nestVal = pAL;
|
||||
pAL->useCt = 0;
|
||||
pAL->allocCt = MIN_ARG_ALLOC_CT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan until we hit a NUL.
|
||||
*/
|
||||
do {
|
||||
pzTxt = SPN_WHITESPACE_CHARS(pzTxt);
|
||||
if (IS_VAR_FIRST_CHAR(*pzTxt))
|
||||
pzTxt = scan_name(pzTxt, pRes);
|
||||
|
||||
else switch (*pzTxt) {
|
||||
case NUL: goto scan_done;
|
||||
case '<': pzTxt = scan_xml(pzTxt, pRes);
|
||||
if (pzTxt == NULL) goto woops;
|
||||
if (*pzTxt == ',') pzTxt++; break;
|
||||
case '#': pzTxt = strchr(pzTxt, NL); break;
|
||||
default: goto woops;
|
||||
}
|
||||
} while (pzTxt != NULL); scan_done:;
|
||||
|
||||
{
|
||||
tArgList * al = pRes->v.nestVal;
|
||||
if (al->useCt == 0) {
|
||||
errno = ENOMSG;
|
||||
goto woops;
|
||||
}
|
||||
if (al->useCt > 1)
|
||||
sort_list(al);
|
||||
}
|
||||
|
||||
return pRes;
|
||||
|
||||
woops:
|
||||
AGFREE(pRes->v.nestVal);
|
||||
AGFREE(pRes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*=export_func optionNestedVal
|
||||
* private:
|
||||
*
|
||||
* what: parse a hierarchical option argument
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Nested value was found on the command line
|
||||
=*/
|
||||
void
|
||||
optionNestedVal(tOptions* pOpts, tOptDesc* pOD)
|
||||
{
|
||||
if (pOpts < OPTPROC_EMIT_LIMIT)
|
||||
return;
|
||||
|
||||
if (pOD->fOptState & OPTST_RESET) {
|
||||
tArgList* pAL = pOD->optCookie;
|
||||
int ct;
|
||||
tCC ** av;
|
||||
|
||||
if (pAL == NULL)
|
||||
return;
|
||||
ct = pAL->useCt;
|
||||
av = pAL->apzArgs;
|
||||
|
||||
while (--ct >= 0) {
|
||||
void * p = (void *)*(av++);
|
||||
optionUnloadNested((tOptionValue const *)p);
|
||||
}
|
||||
|
||||
AGFREE(pOD->optCookie);
|
||||
|
||||
} else {
|
||||
tOptionValue* pOV = optionLoadNested(
|
||||
pOD->optArg.argString, pOD->pz_Name, strlen(pOD->pz_Name));
|
||||
|
||||
if (pOV != NULL)
|
||||
addArgListEntry(&(pOD->optCookie), (void*)pOV);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_special_char
|
||||
*/
|
||||
LOCAL int
|
||||
get_special_char(char const ** ppz, int * ct)
|
||||
{
|
||||
char const * pz = *ppz;
|
||||
|
||||
if (*ct < 3)
|
||||
return '&';
|
||||
|
||||
if (*pz == '#') {
|
||||
int base = 10;
|
||||
int retch;
|
||||
|
||||
pz++;
|
||||
if (*pz == 'x') {
|
||||
base = 16;
|
||||
pz++;
|
||||
}
|
||||
retch = (int)strtoul(pz, (char **)&pz, base);
|
||||
if (*pz != ';')
|
||||
return '&';
|
||||
base = ++pz - *ppz;
|
||||
if (base > *ct)
|
||||
return '&';
|
||||
|
||||
*ct -= base;
|
||||
*ppz = pz;
|
||||
return retch;
|
||||
}
|
||||
|
||||
{
|
||||
int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]);
|
||||
xml_xlate_t const * xlatp = xml_xlate;
|
||||
|
||||
for (;;) {
|
||||
if ( (*ct >= xlatp->xml_len)
|
||||
&& (strncmp(pz, xlatp->xml_txt, xlatp->xml_len) == 0)) {
|
||||
*ppz += xlatp->xml_len;
|
||||
*ct -= xlatp->xml_len;
|
||||
return xlatp->xml_ch;
|
||||
}
|
||||
|
||||
if (--ctr <= 0)
|
||||
break;
|
||||
xlatp++;
|
||||
}
|
||||
}
|
||||
return '&';
|
||||
}
|
||||
|
||||
/*
|
||||
* emit_special_char
|
||||
*/
|
||||
LOCAL void
|
||||
emit_special_char(FILE * fp, int ch)
|
||||
{
|
||||
int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]);
|
||||
xml_xlate_t const * xlatp = xml_xlate;
|
||||
|
||||
putc('&', fp);
|
||||
for (;;) {
|
||||
if (ch == xlatp->xml_ch) {
|
||||
fputs(xlatp->xml_txt, fp);
|
||||
return;
|
||||
}
|
||||
if (--ctr <= 0)
|
||||
break;
|
||||
xlatp++;
|
||||
}
|
||||
fprintf(fp, XML_HEX_BYTE_FMT, (ch & 0xFF));
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/nested.c */
|
||||
@@ -0,0 +1,165 @@
|
||||
|
||||
/**
|
||||
* \file numeric.c
|
||||
*
|
||||
* Time-stamp: "2012-02-25 12:54:32 bkorb"
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*=export_func optionShowRange
|
||||
* private:
|
||||
*
|
||||
* what:
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
* arg: + void * + rng_table + the value range tables +
|
||||
* arg: + int + rng_count + the number of entries +
|
||||
*
|
||||
* doc:
|
||||
* Show information about a numeric option with range constraints.
|
||||
=*/
|
||||
void
|
||||
optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct)
|
||||
{
|
||||
const struct {long const rmin, rmax;} * rng = rng_table;
|
||||
|
||||
char const * pz_indent = BULLET_STR;
|
||||
|
||||
/*
|
||||
* The range is shown only for full usage requests and an error
|
||||
* in this particular option.
|
||||
*/
|
||||
if (pOpts != OPTPROC_EMIT_USAGE) {
|
||||
if (pOpts <= OPTPROC_EMIT_LIMIT)
|
||||
return;
|
||||
pz_indent = ONE_TAB_STR;
|
||||
|
||||
fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName,
|
||||
pOD->pz_Name, pOD->optArg.argInt);
|
||||
pz_indent = "";
|
||||
}
|
||||
|
||||
if (pOD->fOptState & OPTST_SCALED_NUM)
|
||||
fprintf(option_usage_fp, zRangeScaled, pz_indent);
|
||||
|
||||
fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent);
|
||||
pz_indent = (pOpts != OPTPROC_EMIT_USAGE) ? ONE_TAB_STR : DEEP_INDENT_STR;
|
||||
|
||||
for (;;) {
|
||||
if (rng->rmax == LONG_MIN)
|
||||
fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin);
|
||||
else if (rng->rmin == LONG_MIN)
|
||||
fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax);
|
||||
else if (rng->rmax == LONG_MAX)
|
||||
fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin);
|
||||
else
|
||||
fprintf(option_usage_fp, zRange, pz_indent, rng->rmin,
|
||||
rng->rmax);
|
||||
|
||||
if (--rng_ct <= 0) {
|
||||
fputc(NL, option_usage_fp);
|
||||
break;
|
||||
}
|
||||
fputs(zRangeOr, option_usage_fp);
|
||||
rng++;
|
||||
}
|
||||
|
||||
if (pOpts > OPTPROC_EMIT_LIMIT)
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/*=export_func optionNumericVal
|
||||
* private:
|
||||
*
|
||||
* what: process an option with a numeric value.
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Decipher a numeric value.
|
||||
=*/
|
||||
void
|
||||
optionNumericVal(tOptions* pOpts, tOptDesc* pOD )
|
||||
{
|
||||
char* pz;
|
||||
long val;
|
||||
|
||||
/*
|
||||
* Numeric options may have a range associated with it.
|
||||
* If it does, the usage procedure requests that it be
|
||||
* emitted by passing a NULL pOD pointer. Also bail out
|
||||
* if there is no option argument or if we are being reset.
|
||||
*/
|
||||
if ( (pOD == NULL)
|
||||
|| (pOD->optArg.argString == NULL)
|
||||
|| ((pOD->fOptState & OPTST_RESET) != 0))
|
||||
return;
|
||||
|
||||
errno = 0;
|
||||
val = strtol(pOD->optArg.argString, &pz, 0);
|
||||
if ((pz == pOD->optArg.argString) || (errno != 0))
|
||||
goto bad_number;
|
||||
|
||||
if ((pOD->fOptState & OPTST_SCALED_NUM) != 0)
|
||||
switch (*(pz++)) {
|
||||
case NUL: pz--; break;
|
||||
case 't': val *= 1000;
|
||||
case 'g': val *= 1000;
|
||||
case 'm': val *= 1000;
|
||||
case 'k': val *= 1000; break;
|
||||
|
||||
case 'T': val *= 1024;
|
||||
case 'G': val *= 1024;
|
||||
case 'M': val *= 1024;
|
||||
case 'K': val *= 1024; break;
|
||||
|
||||
default: goto bad_number;
|
||||
}
|
||||
|
||||
if (*pz != NUL)
|
||||
goto bad_number;
|
||||
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
pOD->optArg.argInt = val;
|
||||
return;
|
||||
|
||||
bad_number:
|
||||
|
||||
fprintf( stderr, zNotNumber, pOpts->pzProgName, pOD->optArg.argString );
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
|
||||
(*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
|
||||
|
||||
errno = EINVAL;
|
||||
pOD->optArg.argInt = ~0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/numeric.c */
|
||||
@@ -0,0 +1,601 @@
|
||||
/* Parse a time duration and return a seconds count
|
||||
Copyright (C) 2008-2012 Free Software Foundation, Inc.
|
||||
Written by Bruce Korb <bkorb@gnu.org>, 2008.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Specification. */
|
||||
#include "parse-duration.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef NUL
|
||||
#define NUL '\0'
|
||||
#endif
|
||||
|
||||
#define cch_t char const
|
||||
|
||||
typedef enum {
|
||||
NOTHING_IS_DONE,
|
||||
YEAR_IS_DONE,
|
||||
MONTH_IS_DONE,
|
||||
WEEK_IS_DONE,
|
||||
DAY_IS_DONE,
|
||||
HOUR_IS_DONE,
|
||||
MINUTE_IS_DONE,
|
||||
SECOND_IS_DONE
|
||||
} whats_done_t;
|
||||
|
||||
#define SEC_PER_MIN 60
|
||||
#define SEC_PER_HR (SEC_PER_MIN * 60)
|
||||
#define SEC_PER_DAY (SEC_PER_HR * 24)
|
||||
#define SEC_PER_WEEK (SEC_PER_DAY * 7)
|
||||
#define SEC_PER_MONTH (SEC_PER_DAY * 30)
|
||||
#define SEC_PER_YEAR (SEC_PER_DAY * 365)
|
||||
|
||||
#define TIME_MAX 0x7FFFFFFF
|
||||
|
||||
/* Wrapper around strtoul that does not require a cast. */
|
||||
inline static unsigned long
|
||||
str_const_to_ul (cch_t * str, cch_t ** ppz, int base)
|
||||
{
|
||||
return strtoul (str, (char **)ppz, base);
|
||||
}
|
||||
|
||||
/* Wrapper around strtol that does not require a cast. */
|
||||
inline static long
|
||||
str_const_to_l (cch_t * str, cch_t ** ppz, int base)
|
||||
{
|
||||
return strtol (str, (char **)ppz, base);
|
||||
}
|
||||
|
||||
/* Returns BASE + VAL * SCALE, interpreting BASE = BAD_TIME
|
||||
with errno set as an error situation, and returning BAD_TIME
|
||||
with errno set in an error situation. */
|
||||
inline static time_t
|
||||
scale_n_add (time_t base, time_t val, int scale)
|
||||
{
|
||||
if (base == BAD_TIME)
|
||||
{
|
||||
if (errno == 0)
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
if (val > TIME_MAX / scale)
|
||||
{
|
||||
errno = ERANGE;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
val *= scale;
|
||||
if (base > TIME_MAX - val)
|
||||
{
|
||||
errno = ERANGE;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
return base + val;
|
||||
}
|
||||
|
||||
/* After a number HH has been parsed, parse subsequent :MM or :MM:SS. */
|
||||
static time_t
|
||||
parse_hr_min_sec (time_t start, cch_t * pz)
|
||||
{
|
||||
int lpct = 0;
|
||||
|
||||
errno = 0;
|
||||
|
||||
/* For as long as our scanner pointer points to a colon *AND*
|
||||
we've not looped before, then keep looping. (two iterations max) */
|
||||
while ((*pz == ':') && (lpct++ <= 1))
|
||||
{
|
||||
unsigned long v = str_const_to_ul (pz+1, &pz, 10);
|
||||
|
||||
if (errno != 0)
|
||||
return BAD_TIME;
|
||||
|
||||
start = scale_n_add (v, start, 60);
|
||||
|
||||
if (errno != 0)
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
/* allow for trailing spaces */
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
if (*pz != NUL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Parses a value and returns BASE + value * SCALE, interpreting
|
||||
BASE = BAD_TIME with errno set as an error situation, and returning
|
||||
BAD_TIME with errno set in an error situation. */
|
||||
static time_t
|
||||
parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale)
|
||||
{
|
||||
cch_t * pz = *ppz;
|
||||
time_t val;
|
||||
|
||||
if (base == BAD_TIME)
|
||||
return base;
|
||||
|
||||
errno = 0;
|
||||
val = str_const_to_ul (pz, &pz, 10);
|
||||
if (errno != 0)
|
||||
return BAD_TIME;
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
if (pz != endp)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
*ppz = pz;
|
||||
return scale_n_add (base, val, scale);
|
||||
}
|
||||
|
||||
/* Parses the syntax YEAR-MONTH-DAY.
|
||||
PS points into the string, after "YEAR", before "-MONTH-DAY". */
|
||||
static time_t
|
||||
parse_year_month_day (cch_t * pz, cch_t * ps)
|
||||
{
|
||||
time_t res = 0;
|
||||
|
||||
res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR);
|
||||
|
||||
pz++; /* over the first '-' */
|
||||
ps = strchr (pz, '-');
|
||||
if (ps == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH);
|
||||
|
||||
pz++; /* over the second '-' */
|
||||
ps = pz + strlen (pz);
|
||||
return parse_scaled_value (res, &pz, ps, SEC_PER_DAY);
|
||||
}
|
||||
|
||||
/* Parses the syntax YYYYMMDD. */
|
||||
static time_t
|
||||
parse_yearmonthday (cch_t * in_pz)
|
||||
{
|
||||
time_t res = 0;
|
||||
char buf[8];
|
||||
cch_t * pz;
|
||||
|
||||
if (strlen (in_pz) != 8)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
memcpy (buf, in_pz, 4);
|
||||
buf[4] = NUL;
|
||||
pz = buf;
|
||||
res = parse_scaled_value (0, &pz, buf + 4, SEC_PER_YEAR);
|
||||
|
||||
memcpy (buf, in_pz + 4, 2);
|
||||
buf[2] = NUL;
|
||||
pz = buf;
|
||||
res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MONTH);
|
||||
|
||||
memcpy (buf, in_pz + 6, 2);
|
||||
buf[2] = NUL;
|
||||
pz = buf;
|
||||
return parse_scaled_value (res, &pz, buf + 2, SEC_PER_DAY);
|
||||
}
|
||||
|
||||
/* Parses the syntax yy Y mm M ww W dd D. */
|
||||
static time_t
|
||||
parse_YMWD (cch_t * pz)
|
||||
{
|
||||
time_t res = 0;
|
||||
cch_t * ps = strchr (pz, 'Y');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR);
|
||||
pz++;
|
||||
}
|
||||
|
||||
ps = strchr (pz, 'M');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH);
|
||||
pz++;
|
||||
}
|
||||
|
||||
ps = strchr (pz, 'W');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (res, &pz, ps, SEC_PER_WEEK);
|
||||
pz++;
|
||||
}
|
||||
|
||||
ps = strchr (pz, 'D');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (res, &pz, ps, SEC_PER_DAY);
|
||||
pz++;
|
||||
}
|
||||
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
if (*pz != NUL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Parses the syntax HH:MM:SS.
|
||||
PS points into the string, after "HH", before ":MM:SS". */
|
||||
static time_t
|
||||
parse_hour_minute_second (cch_t * pz, cch_t * ps)
|
||||
{
|
||||
time_t res = 0;
|
||||
|
||||
res = parse_scaled_value (0, &pz, ps, SEC_PER_HR);
|
||||
|
||||
pz++;
|
||||
ps = strchr (pz, ':');
|
||||
if (ps == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN);
|
||||
|
||||
pz++;
|
||||
ps = pz + strlen (pz);
|
||||
return parse_scaled_value (res, &pz, ps, 1);
|
||||
}
|
||||
|
||||
/* Parses the syntax HHMMSS. */
|
||||
static time_t
|
||||
parse_hourminutesecond (cch_t * in_pz)
|
||||
{
|
||||
time_t res = 0;
|
||||
char buf[4];
|
||||
cch_t * pz;
|
||||
|
||||
if (strlen (in_pz) != 6)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
memcpy (buf, in_pz, 2);
|
||||
buf[2] = NUL;
|
||||
pz = buf;
|
||||
res = parse_scaled_value (0, &pz, buf + 2, SEC_PER_HR);
|
||||
|
||||
memcpy (buf, in_pz + 2, 2);
|
||||
buf[2] = NUL;
|
||||
pz = buf;
|
||||
res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MIN);
|
||||
|
||||
memcpy (buf, in_pz + 4, 2);
|
||||
buf[2] = NUL;
|
||||
pz = buf;
|
||||
return parse_scaled_value (res, &pz, buf + 2, 1);
|
||||
}
|
||||
|
||||
/* Parses the syntax hh H mm M ss S. */
|
||||
static time_t
|
||||
parse_HMS (cch_t * pz)
|
||||
{
|
||||
time_t res = 0;
|
||||
cch_t * ps = strchr (pz, 'H');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (0, &pz, ps, SEC_PER_HR);
|
||||
pz++;
|
||||
}
|
||||
|
||||
ps = strchr (pz, 'M');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN);
|
||||
pz++;
|
||||
}
|
||||
|
||||
ps = strchr (pz, 'S');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_scaled_value (res, &pz, ps, 1);
|
||||
pz++;
|
||||
}
|
||||
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
if (*pz != NUL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Parses a time (hours, minutes, seconds) specification in either syntax. */
|
||||
static time_t
|
||||
parse_time (cch_t * pz)
|
||||
{
|
||||
cch_t * ps;
|
||||
time_t res = 0;
|
||||
|
||||
/*
|
||||
* Scan for a hyphen
|
||||
*/
|
||||
ps = strchr (pz, ':');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_hour_minute_second (pz, ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try for a 'H', 'M' or 'S' suffix
|
||||
*/
|
||||
else if (ps = strpbrk (pz, "HMS"),
|
||||
ps == NULL)
|
||||
{
|
||||
/* Its a YYYYMMDD format: */
|
||||
res = parse_hourminutesecond (pz);
|
||||
}
|
||||
|
||||
else
|
||||
res = parse_HMS (pz);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Returns a substring of the given string, with spaces at the beginning and at
|
||||
the end destructively removed, per SNOBOL. */
|
||||
static char *
|
||||
trim (char * pz)
|
||||
{
|
||||
/* trim leading white space */
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
|
||||
/* trim trailing white space */
|
||||
{
|
||||
char * pe = pz + strlen (pz);
|
||||
while ((pe > pz) && isspace ((unsigned char)pe[-1]))
|
||||
pe--;
|
||||
*pe = NUL;
|
||||
}
|
||||
|
||||
return pz;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the year/months/days of a time period
|
||||
*/
|
||||
static time_t
|
||||
parse_period (cch_t * in_pz)
|
||||
{
|
||||
char * pT;
|
||||
char * ps;
|
||||
char * pz = strdup (in_pz);
|
||||
void * fptr = pz;
|
||||
time_t res = 0;
|
||||
|
||||
if (pz == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
pT = strchr (pz, 'T');
|
||||
if (pT != NULL)
|
||||
{
|
||||
*(pT++) = NUL;
|
||||
pz = trim (pz);
|
||||
pT = trim (pT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan for a hyphen
|
||||
*/
|
||||
ps = strchr (pz, '-');
|
||||
if (ps != NULL)
|
||||
{
|
||||
res = parse_year_month_day (pz, ps);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try for a 'Y', 'M' or 'D' suffix
|
||||
*/
|
||||
else if (ps = strpbrk (pz, "YMWD"),
|
||||
ps == NULL)
|
||||
{
|
||||
/* Its a YYYYMMDD format: */
|
||||
res = parse_yearmonthday (pz);
|
||||
}
|
||||
|
||||
else
|
||||
res = parse_YMWD (pz);
|
||||
|
||||
if ((errno == 0) && (pT != NULL))
|
||||
{
|
||||
time_t val = parse_time (pT);
|
||||
res = scale_n_add (res, val, 1);
|
||||
}
|
||||
|
||||
free (fptr);
|
||||
return res;
|
||||
}
|
||||
|
||||
static time_t
|
||||
parse_non_iso8601 (cch_t * pz)
|
||||
{
|
||||
whats_done_t whatd_we_do = NOTHING_IS_DONE;
|
||||
|
||||
time_t res = 0;
|
||||
|
||||
do {
|
||||
time_t val;
|
||||
|
||||
errno = 0;
|
||||
val = str_const_to_l (pz, &pz, 10);
|
||||
if (errno != 0)
|
||||
goto bad_time;
|
||||
|
||||
/* IF we find a colon, then we're going to have a seconds value.
|
||||
We will not loop here any more. We cannot already have parsed
|
||||
a minute value and if we've parsed an hour value, then the result
|
||||
value has to be less than an hour. */
|
||||
if (*pz == ':')
|
||||
{
|
||||
if (whatd_we_do >= MINUTE_IS_DONE)
|
||||
break;
|
||||
|
||||
val = parse_hr_min_sec (val, pz);
|
||||
|
||||
if ((whatd_we_do == HOUR_IS_DONE) && (val >= SEC_PER_HR))
|
||||
break;
|
||||
|
||||
return scale_n_add (res, val, 1);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned int mult;
|
||||
|
||||
/* Skip over white space following the number we just parsed. */
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
|
||||
switch (*pz)
|
||||
{
|
||||
default: goto bad_time;
|
||||
case NUL:
|
||||
return scale_n_add (res, val, 1);
|
||||
|
||||
case 'y': case 'Y':
|
||||
if (whatd_we_do >= YEAR_IS_DONE)
|
||||
goto bad_time;
|
||||
mult = SEC_PER_YEAR;
|
||||
whatd_we_do = YEAR_IS_DONE;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (whatd_we_do >= MONTH_IS_DONE)
|
||||
goto bad_time;
|
||||
mult = SEC_PER_MONTH;
|
||||
whatd_we_do = MONTH_IS_DONE;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
if (whatd_we_do >= WEEK_IS_DONE)
|
||||
goto bad_time;
|
||||
mult = SEC_PER_WEEK;
|
||||
whatd_we_do = WEEK_IS_DONE;
|
||||
break;
|
||||
|
||||
case 'd': case 'D':
|
||||
if (whatd_we_do >= DAY_IS_DONE)
|
||||
goto bad_time;
|
||||
mult = SEC_PER_DAY;
|
||||
whatd_we_do = DAY_IS_DONE;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
if (whatd_we_do >= HOUR_IS_DONE)
|
||||
goto bad_time;
|
||||
mult = SEC_PER_HR;
|
||||
whatd_we_do = HOUR_IS_DONE;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (whatd_we_do >= MINUTE_IS_DONE)
|
||||
goto bad_time;
|
||||
mult = SEC_PER_MIN;
|
||||
whatd_we_do = MINUTE_IS_DONE;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
mult = 1;
|
||||
whatd_we_do = SECOND_IS_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
res = scale_n_add (res, val, mult);
|
||||
|
||||
pz++;
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
if (*pz == NUL)
|
||||
return res;
|
||||
|
||||
if (! isdigit ((unsigned char)*pz))
|
||||
break;
|
||||
}
|
||||
|
||||
} while (whatd_we_do < SECOND_IS_DONE);
|
||||
|
||||
bad_time:
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
|
||||
time_t
|
||||
parse_duration (char const * pz)
|
||||
{
|
||||
while (isspace ((unsigned char)*pz))
|
||||
pz++;
|
||||
|
||||
switch (*pz)
|
||||
{
|
||||
case 'P':
|
||||
return parse_period (pz + 1);
|
||||
|
||||
case 'T':
|
||||
return parse_time (pz + 1);
|
||||
|
||||
default:
|
||||
if (isdigit ((unsigned char)*pz))
|
||||
return parse_non_iso8601 (pz);
|
||||
|
||||
errno = EINVAL;
|
||||
return BAD_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "gnu"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of parse-duration.c */
|
||||
@@ -0,0 +1,90 @@
|
||||
/* Parse a time duration and return a seconds count
|
||||
Copyright (C) 2008-2012 Free Software Foundation, Inc.
|
||||
Written by Bruce Korb <bkorb@gnu.org>, 2008.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
|
||||
Readers and users of this function are referred to the ISO-8601
|
||||
specification, with particular attention to "Durations".
|
||||
|
||||
At the time of writing, this worked:
|
||||
|
||||
http://en.wikipedia.org/wiki/ISO_8601#Durations
|
||||
|
||||
The string must start with a 'P', 'T' or a digit.
|
||||
|
||||
==== if it is a digit
|
||||
|
||||
the string may contain: NNN Y NNN M NNN W NNN d NNN h NNN m NNN s
|
||||
This represents NNN years, NNN months, NNN weeks, NNN days, NNN hours,
|
||||
NNN minutes and NNN seconds.
|
||||
The embedded white space is optional.
|
||||
These terms must appear in this order.
|
||||
Case is significant: 'M' is months and 'm' is minutes.
|
||||
The final "s" is optional.
|
||||
All of the terms ("NNN" plus designator) are optional.
|
||||
Minutes and seconds may optionally be represented as NNN:NNN.
|
||||
Also, hours, minute and seconds may be represented as NNN:NNN:NNN.
|
||||
There is no limitation on the value of any of the terms, except
|
||||
that the final result must fit in a time_t value.
|
||||
|
||||
==== if it is a 'P' or 'T', please see ISO-8601 for a rigorous definition.
|
||||
|
||||
The 'P' term may be followed by any of three formats:
|
||||
yyyymmdd
|
||||
yy-mm-dd
|
||||
yy Y mm M ww W dd D
|
||||
|
||||
or it may be empty and followed by a 'T'. The "yyyymmdd" must be eight
|
||||
digits long.
|
||||
|
||||
NOTE! Months are always 30 days and years are always 365 days long.
|
||||
5 years is always 1825 days, not 1826 or 1827 depending on leap year
|
||||
considerations. 3 months is always 90 days. There is no consideration
|
||||
for how many days are in the current, next or previous months.
|
||||
|
||||
For the final format:
|
||||
* Embedded white space is allowed, but it is optional.
|
||||
* All of the terms are optional. Any or all-but-one may be omitted.
|
||||
* The meanings are yy years, mm months, ww weeks and dd days.
|
||||
* The terms must appear in this order.
|
||||
|
||||
==== The 'T' term may be followed by any of these formats:
|
||||
|
||||
hhmmss
|
||||
hh:mm:ss
|
||||
hh H mm M ss S
|
||||
|
||||
For the final format:
|
||||
* Embedded white space is allowed, but it is optional.
|
||||
* All of the terms are optional. Any or all-but-one may be omitted.
|
||||
* The terms must appear in this order.
|
||||
|
||||
*/
|
||||
#ifndef GNULIB_PARSE_DURATION_H
|
||||
#define GNULIB_PARSE_DURATION_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/* Return value when a valid duration cannot be parsed. */
|
||||
#define BAD_TIME ((time_t)~0)
|
||||
|
||||
/* Parses the given string. If it has the syntax of a valid duration,
|
||||
this duration is returned. Otherwise, the return value is BAD_TIME,
|
||||
and errno is set to either EINVAL (bad syntax) or ERANGE (out of range). */
|
||||
extern time_t parse_duration (char const * in_pz);
|
||||
|
||||
#endif /* GNULIB_PARSE_DURATION_H */
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
/**
|
||||
* \file pgusage.c
|
||||
*
|
||||
* Time-stamp: "2012-02-28 19:49:32 bkorb"
|
||||
*
|
||||
* Automated Options Paged Usage module.
|
||||
*
|
||||
* This routine will run run-on options through a pager so the
|
||||
* user may examine, print or edit them at their leisure.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*=export_func optionPagedUsage
|
||||
* private:
|
||||
*
|
||||
* what: Decipher a boolean value
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Run the usage output through a pager.
|
||||
* This is very handy if it is very long.
|
||||
* This is disabled on platforms without a working fork() function.
|
||||
=*/
|
||||
void
|
||||
optionPagedUsage(tOptions * pOptions, tOptDesc * pOD)
|
||||
{
|
||||
#if ! defined(HAVE_WORKING_FORK)
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0)
|
||||
return;
|
||||
|
||||
(*pOptions->pUsageProc)(pOptions, EXIT_SUCCESS);
|
||||
#else
|
||||
static pid_t my_pid;
|
||||
char zPageUsage[ 1024 ];
|
||||
|
||||
/*
|
||||
* IF we are being called after the usage proc is done
|
||||
* (and thus has called "exit(2)")
|
||||
* THEN invoke the pager to page through the usage file we created.
|
||||
*/
|
||||
switch (pagerState) {
|
||||
case PAGER_STATE_INITIAL:
|
||||
{
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0)
|
||||
return;
|
||||
|
||||
my_pid = getpid();
|
||||
snprintf(zPageUsage, sizeof(zPageUsage), TMP_USAGE_FMT, (tAoUL)my_pid);
|
||||
unlink(zPageUsage);
|
||||
|
||||
/*
|
||||
* Set usage output to this temporary file
|
||||
*/
|
||||
option_usage_fp = fopen(zPageUsage, "w" FOPEN_BINARY_FLAG);
|
||||
if (option_usage_fp == NULL)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
pagerState = PAGER_STATE_READY;
|
||||
|
||||
/*
|
||||
* Set up so this routine gets called during the exit logic
|
||||
*/
|
||||
atexit((void(*)(void))optionPagedUsage);
|
||||
|
||||
/*
|
||||
* The usage procedure will now put the usage information into
|
||||
* the temporary file we created above.
|
||||
*/
|
||||
(*pOptions->pUsageProc)(pOptions, EXIT_SUCCESS);
|
||||
|
||||
/* NOTREACHED */
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
case PAGER_STATE_READY:
|
||||
{
|
||||
tCC* pzPager = (tCC*)getenv(PAGER_NAME);
|
||||
|
||||
/*
|
||||
* Use the "more(1)" program if "PAGER" has not been defined
|
||||
*/
|
||||
if (pzPager == NULL)
|
||||
pzPager = MORE_STR;
|
||||
|
||||
/*
|
||||
* Page the file and remove it when done.
|
||||
*/
|
||||
snprintf(zPageUsage, sizeof(zPageUsage), PAGE_USAGE_FMT, pzPager,
|
||||
(tAoUL)my_pid);
|
||||
fclose(stderr);
|
||||
dup2(STDOUT_FILENO, STDERR_FILENO);
|
||||
|
||||
(void)system(zPageUsage);
|
||||
}
|
||||
|
||||
case PAGER_STATE_CHILD:
|
||||
/*
|
||||
* This is a child process used in creating shell script usage.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/pgusage.c */
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* Prototypes for autoopts
|
||||
* Generated Sun May 6 16:21:08 PDT 2012
|
||||
*/
|
||||
#ifndef AUTOOPTS_PROTO_H_GUARD
|
||||
#define AUTOOPTS_PROTO_H_GUARD 1
|
||||
|
||||
#ifndef LOCAL
|
||||
# define LOCAL extern
|
||||
# define REDEF_LOCAL 1
|
||||
#else
|
||||
# undef REDEF_LOCAL
|
||||
#endif
|
||||
/*
|
||||
* Extracted from autoopts.c
|
||||
*/
|
||||
LOCAL void *
|
||||
ao_malloc(size_t sz);
|
||||
|
||||
LOCAL void *
|
||||
ao_realloc(void *p, size_t sz);
|
||||
|
||||
LOCAL char *
|
||||
ao_strdup(char const *str);
|
||||
|
||||
LOCAL tSuccess
|
||||
handle_opt(tOptions * pOpts, tOptState* pOptState);
|
||||
|
||||
LOCAL tSuccess
|
||||
immediate_opts(tOptions * pOpts);
|
||||
|
||||
LOCAL tSuccess
|
||||
regular_opts(tOptions * pOpts);
|
||||
|
||||
/*
|
||||
* Extracted from check.c
|
||||
*/
|
||||
LOCAL bool
|
||||
is_consistent(tOptions * pOpts);
|
||||
|
||||
/*
|
||||
* Extracted from configfile.c
|
||||
*/
|
||||
LOCAL void
|
||||
intern_file_load(tOptions* pOpts);
|
||||
|
||||
LOCAL char*
|
||||
parse_attrs(tOptions * pOpts, char * pzText, tOptionLoadMode * pMode,
|
||||
tOptionValue * pType);
|
||||
|
||||
LOCAL tSuccess
|
||||
validate_struct(tOptions * pOpts, char const * pzProgram);
|
||||
|
||||
/*
|
||||
* Extracted from env.c
|
||||
*/
|
||||
LOCAL void
|
||||
doPrognameEnv(tOptions * pOpts, teEnvPresetType type);
|
||||
|
||||
LOCAL void
|
||||
env_presets(tOptions * pOpts, teEnvPresetType type);
|
||||
|
||||
/*
|
||||
* Extracted from find.c
|
||||
*/
|
||||
LOCAL tSuccess
|
||||
opt_find_long(tOptions * pOpts, char const * opt_name, tOptState * pOptState);
|
||||
|
||||
LOCAL tSuccess
|
||||
opt_find_short(tOptions* pOpts, uint_t optValue, tOptState* pOptState);
|
||||
|
||||
LOCAL tSuccess
|
||||
get_opt_arg(tOptions * pOpts, tOptState * pOptState);
|
||||
|
||||
LOCAL tSuccess
|
||||
find_opt(tOptions * pOpts, tOptState * pOptState);
|
||||
|
||||
/*
|
||||
* Extracted from load.c
|
||||
*/
|
||||
LOCAL void
|
||||
mungeString(char* pzTxt, tOptionLoadMode mode);
|
||||
|
||||
LOCAL void
|
||||
loadOptionLine(
|
||||
tOptions* pOpts,
|
||||
tOptState* pOS,
|
||||
char* pzLine,
|
||||
tDirection direction,
|
||||
tOptionLoadMode load_mode );
|
||||
|
||||
/*
|
||||
* Extracted from nested.c
|
||||
*/
|
||||
LOCAL void
|
||||
unload_arg_list(tArgList* pAL);
|
||||
|
||||
LOCAL tOptionValue*
|
||||
optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen);
|
||||
|
||||
LOCAL int
|
||||
get_special_char(char const ** ppz, int * ct);
|
||||
|
||||
LOCAL void
|
||||
emit_special_char(FILE * fp, int ch);
|
||||
|
||||
/*
|
||||
* Extracted from sort.c
|
||||
*/
|
||||
LOCAL void
|
||||
optionSort(tOptions* pOpts);
|
||||
|
||||
/*
|
||||
* Extracted from stack.c
|
||||
*/
|
||||
LOCAL void
|
||||
addArgListEntry(void** ppAL, void* entry);
|
||||
|
||||
/*
|
||||
* Extracted from usage.c
|
||||
*/
|
||||
LOCAL void
|
||||
set_usage_flags(tOptions * opts, char const * flg_txt);
|
||||
|
||||
#ifdef REDEF_LOCAL
|
||||
# undef LOCAL
|
||||
# define LOCAL
|
||||
#endif
|
||||
#endif /* AUTOOPTS_PROTO_H_GUARD */
|
||||
@@ -0,0 +1,361 @@
|
||||
|
||||
/**
|
||||
* \file putshell.c
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:14:18 bkorb"
|
||||
*
|
||||
* This module will interpret the options set in the tOptions
|
||||
* structure and print them to standard out in a fashion that
|
||||
* will allow them to be interpreted by the Bourne or Korn shells.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static void
|
||||
print_quot_str(char const * pzStr);
|
||||
|
||||
static void
|
||||
print_enumeration(tOptions * pOpts, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
print_membership(tOptions * pOpts, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
print_stacked_arg(tOptions * pOpts, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
print_reordering(tOptions * pOpts);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/*
|
||||
* Make sure embedded single quotes come out okay. The initial quote has
|
||||
* been emitted and the closing quote will be upon return.
|
||||
*/
|
||||
static void
|
||||
print_quot_str(char const * pzStr)
|
||||
{
|
||||
/*
|
||||
* Handle empty strings to make the rest of the logic simpler.
|
||||
*/
|
||||
if ((pzStr == NULL) || (*pzStr == NUL)) {
|
||||
fputs(EMPTY_ARG, stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit any single quotes/apostrophes at the start of the string and
|
||||
* bail if that is all we need to do.
|
||||
*/
|
||||
while (*pzStr == '\'') {
|
||||
fputs(QUOT_APOS, stdout);
|
||||
pzStr++;
|
||||
}
|
||||
if (*pzStr == NUL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Start the single quote string
|
||||
*/
|
||||
fputc('\'', stdout);
|
||||
for (;;) {
|
||||
char const * pz = strchr(pzStr, '\'');
|
||||
if (pz == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Emit the string up to the single quote (apostrophe) we just found.
|
||||
*/
|
||||
(void)fwrite(pzStr, (size_t)(pz - pzStr), (size_t)1, stdout);
|
||||
fputc('\'', stdout);
|
||||
pzStr = pz;
|
||||
|
||||
/*
|
||||
* Emit an escaped apostrophe for every one we find.
|
||||
* If that ends the string, do not re-open the single quotes.
|
||||
*/
|
||||
while (*++pzStr == '\'') fputs("\\'", stdout);
|
||||
if (*pzStr == NUL)
|
||||
return;
|
||||
|
||||
fputc('\'', stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we broke out of the loop, we must still emit the remaining text
|
||||
* and then close the single quote string.
|
||||
*/
|
||||
fputs(pzStr, stdout);
|
||||
fputc('\'', stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
print_enumeration(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
uintptr_t e_val = pOD->optArg.argEnum;
|
||||
printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
|
||||
|
||||
/*
|
||||
* Convert value to string, print that and restore numeric value.
|
||||
*/
|
||||
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
|
||||
printf(QUOT_ARG_FMT, pOD->optArg.argString);
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG)
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->optArg.argEnum = e_val;
|
||||
|
||||
printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
|
||||
}
|
||||
|
||||
static void
|
||||
print_membership(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
char const * pz;
|
||||
uintptr_t val = 1;
|
||||
printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
(int)(uintptr_t)(pOD->optCookie));
|
||||
pOD->optCookie = (void*)(uintptr_t)~0UL;
|
||||
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
|
||||
|
||||
/*
|
||||
* We are building the typeset list. The list returned starts with
|
||||
* 'none + ' for use by option saving stuff. We must ignore that.
|
||||
*/
|
||||
pz = pOD->optArg.argString + 7;
|
||||
while (*pz != NUL) {
|
||||
printf("typeset -x -i %s_", pOD->pz_NAME);
|
||||
pz = SPN_PLUS_N_SPACE_CHARS(pz);
|
||||
|
||||
for (;;) {
|
||||
int ch = *(pz++);
|
||||
if (IS_LOWER_CASE_CHAR(ch)) fputc(toupper(ch), stdout);
|
||||
else if (IS_UPPER_CASE_CHAR(ch)) fputc(ch, stdout);
|
||||
else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done;
|
||||
else if (ch == NUL) { pz--; goto name_done; }
|
||||
else fputc('_', stdout);
|
||||
} name_done:;
|
||||
printf(SHOW_VAL_FMT, (unsigned long)val);
|
||||
val <<= 1;
|
||||
}
|
||||
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->optArg.argString = NULL;
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
static void
|
||||
print_stacked_arg(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
tArgList* pAL = (tArgList*)pOD->optCookie;
|
||||
tCC** ppz = pAL->apzArgs;
|
||||
int ct = pAL->useCt;
|
||||
|
||||
printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct);
|
||||
|
||||
while (--ct >= 0) {
|
||||
printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
pAL->useCt - ct);
|
||||
print_quot_str(*(ppz++));
|
||||
printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
pAL->useCt - ct);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_reordering(tOptions * pOpts)
|
||||
{
|
||||
unsigned int optIx;
|
||||
|
||||
fputs(set_dash, stdout);
|
||||
|
||||
for (optIx = pOpts->curOptIdx;
|
||||
optIx < pOpts->origArgCt;
|
||||
optIx++) {
|
||||
|
||||
char* pzArg = pOpts->origArgVect[ optIx ];
|
||||
|
||||
if (strchr(pzArg, '\'') == NULL)
|
||||
printf(arg_fmt, pzArg);
|
||||
|
||||
else {
|
||||
fputs(" '", stdout);
|
||||
for (;;) {
|
||||
char ch = *(pzArg++);
|
||||
switch (ch) {
|
||||
case '\'': fputs(apostrophy, stdout); break;
|
||||
case NUL: goto arg_done;
|
||||
default: fputc(ch, stdout); break;
|
||||
}
|
||||
} arg_done:;
|
||||
fputc('\'', stdout);
|
||||
}
|
||||
}
|
||||
fputs(init_optct, stdout);
|
||||
}
|
||||
|
||||
/*=export_func optionPutShell
|
||||
* what: write a portable shell script to parse options
|
||||
* private:
|
||||
* arg: tOptions*, pOpts, the program options descriptor
|
||||
* doc: This routine will emit portable shell script text for parsing
|
||||
* the options described in the option definitions.
|
||||
=*/
|
||||
void
|
||||
optionPutShell(tOptions* pOpts)
|
||||
{
|
||||
int optIx = 0;
|
||||
|
||||
printf(zOptCtFmt, pOpts->curOptIdx-1);
|
||||
|
||||
do {
|
||||
tOptDesc* pOD = pOpts->pOptDesc + optIx;
|
||||
|
||||
if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Equivalence classes are hard to deal with. Where the
|
||||
* option data wind up kind of squishes around. For the purposes
|
||||
* of emitting shell state, they are not recommended, but we'll
|
||||
* do something. I guess we'll emit the equivalenced-to option
|
||||
* at the point in time when the base option is found.
|
||||
*/
|
||||
if (pOD->optEquivIndex != NO_EQUIVALENT)
|
||||
continue; /* equivalence to a different option */
|
||||
|
||||
/*
|
||||
* Equivalenced to a different option. Process the current option
|
||||
* as the equivalenced-to option. Keep the persistent state bits,
|
||||
* but copy over the set-state bits.
|
||||
*/
|
||||
if (pOD->optActualIndex != optIx) {
|
||||
tOptDesc* p = pOpts->pOptDesc + pOD->optActualIndex;
|
||||
p->optArg = pOD->optArg;
|
||||
p->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK;
|
||||
printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME);
|
||||
pOD = p;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the argument type is a set membership bitmask, then we always
|
||||
* emit the thing. We do this because it will always have some sort
|
||||
* of bitmask value and we need to emit the bit values.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
|
||||
print_membership(pOpts, pOD);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF the option was either specified or it wakes up enabled,
|
||||
* then we will emit information. Otherwise, skip it.
|
||||
* The idea is that if someone defines an option to initialize
|
||||
* enabled, we should tell our shell script that it is enabled.
|
||||
*/
|
||||
if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Handle stacked arguments
|
||||
*/
|
||||
if ( (pOD->fOptState & OPTST_STACKED)
|
||||
&& (pOD->optCookie != NULL) ) {
|
||||
print_stacked_arg(pOpts, pOD);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the argument has been disabled,
|
||||
* Then set its value to the disablement string
|
||||
*/
|
||||
if ((pOD->fOptState & OPTST_DISABLED) != 0) {
|
||||
printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
(pOD->pz_DisablePfx != NULL)
|
||||
? pOD->pz_DisablePfx : "false");
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the argument type is numeric, the last arg pointer
|
||||
* is really the VALUE of the string that was pointed to.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) {
|
||||
printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
(int)pOD->optArg.argInt);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the argument type is an enumeration, then it is much
|
||||
* like a text value, except we call the callback function
|
||||
* to emit the value corresponding to the "optArg" number.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
|
||||
print_enumeration(pOpts, pOD);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the argument type is numeric, the last arg pointer
|
||||
* is really the VALUE of the string that was pointed to.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) {
|
||||
printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
(pOD->optArg.argBool == 0) ? "false" : "true");
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF the option has an empty value,
|
||||
* THEN we set the argument to the occurrence count.
|
||||
*/
|
||||
if ( (pOD->optArg.argString == NULL)
|
||||
|| (pOD->optArg.argString[0] == NUL) ) {
|
||||
|
||||
printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
|
||||
pOD->optOccCt);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* This option has a text value
|
||||
*/
|
||||
printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
|
||||
print_quot_str(pOD->optArg.argString);
|
||||
printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME);
|
||||
|
||||
} while (++optIx < pOpts->presetOptCt );
|
||||
|
||||
if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
|
||||
&& (pOpts->curOptIdx < pOpts->origArgCt))
|
||||
print_reordering(pOpts);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/putshell.c */
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
|
||||
/**
|
||||
* \file reset.c
|
||||
*
|
||||
* Time-stamp: "2011-05-24 18:07:16 bkorb"
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
static void
|
||||
optionReset( tOptions* pOpts, tOptDesc* pOD )
|
||||
{
|
||||
pOD->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
pOD->fOptState |= OPTST_RESET;
|
||||
if (pOD->pOptProc != NULL)
|
||||
pOD->pOptProc(pOpts, pOD);
|
||||
pOD->optArg.argString =
|
||||
pOpts->originalOptArgArray[ pOD->optIndex ].argString;
|
||||
pOD->optCookie = pOpts->originalOptArgCookie[ pOD->optIndex ];
|
||||
pOD->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
optionResetEverything(tOptions * pOpts)
|
||||
{
|
||||
tOptDesc * pOD = pOpts->pOptDesc;
|
||||
int ct = pOpts->presetOptCt;
|
||||
|
||||
for (;;) {
|
||||
optionReset(pOpts, pOD);
|
||||
|
||||
if (--ct <= 0)
|
||||
break;
|
||||
pOD++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionResetOpt
|
||||
* private:
|
||||
*
|
||||
* what: Reset the value of an option
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* This code will cause another option to be reset to its initial state.
|
||||
* For example, --reset=foo will cause the --foo option to be reset.
|
||||
=*/
|
||||
void
|
||||
optionResetOpt( tOptions* pOpts, tOptDesc* pOD )
|
||||
{
|
||||
static bool reset_active = false;
|
||||
|
||||
tOptState opt_state = OPTSTATE_INITIALIZER(DEFINED);
|
||||
char const * pzArg = pOD->optArg.argString;
|
||||
tSuccess succ;
|
||||
|
||||
if (reset_active)
|
||||
return;
|
||||
|
||||
if ( (! HAS_originalOptArgArray(pOpts))
|
||||
|| (pOpts->originalOptArgCookie == NULL)) {
|
||||
fputs(zResetNotConfig, stderr);
|
||||
_exit(EX_SOFTWARE);
|
||||
}
|
||||
|
||||
if ((pzArg == NULL) || (*pzArg == NUL)) {
|
||||
fputs(zNoResetArg, stderr);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
assert(0 == 1);
|
||||
}
|
||||
|
||||
reset_active = true;
|
||||
|
||||
if (pzArg[1] == NUL) {
|
||||
if (*pzArg == '*') {
|
||||
optionResetEverything(pOpts);
|
||||
reset_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
succ = opt_find_short(pOpts, (tAoUC)*pzArg, &opt_state);
|
||||
if (! SUCCESSFUL(succ)) {
|
||||
fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
assert(0 == 1);
|
||||
}
|
||||
} else {
|
||||
succ = opt_find_long(pOpts, (char *)pzArg, &opt_state);
|
||||
if (! SUCCESSFUL(succ)) {
|
||||
fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg);
|
||||
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
|
||||
/* NOTREACHED */
|
||||
assert(0 == 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We've found the indicated option. Turn off all non-persistent
|
||||
* flags because we're forcing the option back to its initialized state.
|
||||
* Call any callout procedure to handle whatever it needs to.
|
||||
* Finally, clear the reset flag, too.
|
||||
*/
|
||||
optionReset(pOpts, opt_state.pOD);
|
||||
reset_active = false;
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/reset.c */
|
||||
@@ -0,0 +1,228 @@
|
||||
|
||||
/*
|
||||
* \file restore.c
|
||||
*
|
||||
* Time-stamp: "2010-08-22 11:04:00 bkorb"
|
||||
*
|
||||
* This module's routines will save the current option state to memory
|
||||
* and restore it. If saved prior to the initial optionProcess call,
|
||||
* then the initial state will be restored.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*
|
||||
* optionFixupSavedOpts Really, it just wipes out option state for
|
||||
* options that are troublesome to copy. viz., stacked strings and
|
||||
* hierarcicaly valued option args. We do duplicate string args that
|
||||
* have been marked as allocated though.
|
||||
*/
|
||||
static void
|
||||
fixupSavedOptionArgs(tOptions* pOpts)
|
||||
{
|
||||
tOptions* p = pOpts->pSavedState;
|
||||
tOptDesc* pOD = pOpts->pOptDesc;
|
||||
int ct = pOpts->optCt;
|
||||
|
||||
/*
|
||||
* Make sure that allocated stuff is only referenced in the
|
||||
* archived copy of the data.
|
||||
*/
|
||||
for (; ct-- > 0; pOD++) {
|
||||
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
|
||||
case OPARG_TYPE_STRING:
|
||||
if (pOD->fOptState & OPTST_STACKED) {
|
||||
tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
|
||||
q->optCookie = NULL;
|
||||
}
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
|
||||
AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg");
|
||||
}
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_HIERARCHY:
|
||||
{
|
||||
tOptDesc* q = p->pOptDesc + (pOD - pOpts->pOptDesc);
|
||||
q->optCookie = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*=export_func optionSaveState
|
||||
*
|
||||
* what: saves the option state to memory
|
||||
* arg: tOptions*, pOpts, program options descriptor
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This routine will allocate enough memory to save the current option
|
||||
* processing state. If this routine has been called before, that memory
|
||||
* will be reused. You may only save one copy of the option state. This
|
||||
* routine may be called before optionProcess(3AO). If you do call it
|
||||
* before the first call to optionProcess, then you may also change the
|
||||
* contents of argc/argv after you call optionRestore(3AO)
|
||||
*
|
||||
* In fact, more strongly put: it is safest to only use this function
|
||||
* before having processed any options. In particular, the saving and
|
||||
* restoring of stacked string arguments and hierarchical values is
|
||||
* disabled. The values are not saved.
|
||||
*
|
||||
* err: If it fails to allocate the memory,
|
||||
* it will print a message to stderr and exit.
|
||||
* Otherwise, it will always succeed.
|
||||
=*/
|
||||
void
|
||||
optionSaveState(tOptions* pOpts)
|
||||
{
|
||||
tOptions* p = (tOptions*)pOpts->pSavedState;
|
||||
|
||||
if (p == NULL) {
|
||||
size_t sz = sizeof(*pOpts) + (pOpts->optCt * sizeof(tOptDesc));
|
||||
p = AGALOC(sz, "saved option state");
|
||||
if (p == NULL) {
|
||||
tCC* pzName = pOpts->pzProgName;
|
||||
if (pzName == NULL) {
|
||||
pzName = pOpts->pzPROGNAME;
|
||||
if (pzName == NULL)
|
||||
pzName = zNil;
|
||||
}
|
||||
fprintf(stderr, zCantSave, pzName, sz);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pOpts->pSavedState = p;
|
||||
}
|
||||
|
||||
memcpy(p, pOpts, sizeof(*p));
|
||||
memcpy(p + 1, pOpts->pOptDesc, p->optCt * sizeof(tOptDesc));
|
||||
|
||||
fixupSavedOptionArgs(pOpts);
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionRestore
|
||||
*
|
||||
* what: restore option state from memory copy
|
||||
* arg: tOptions*, pOpts, program options descriptor
|
||||
*
|
||||
* doc: Copy back the option state from saved memory.
|
||||
* The allocated memory is left intact, so this routine can be
|
||||
* called repeatedly without having to call optionSaveState again.
|
||||
* If you are restoring a state that was saved before the first call
|
||||
* to optionProcess(3AO), then you may change the contents of the
|
||||
* argc/argv parameters to optionProcess.
|
||||
*
|
||||
* err: If you have not called @code{optionSaveState} before, a diagnostic is
|
||||
* printed to @code{stderr} and exit is called.
|
||||
=*/
|
||||
void
|
||||
optionRestore(tOptions* pOpts)
|
||||
{
|
||||
tOptions* p = (tOptions*)pOpts->pSavedState;
|
||||
|
||||
if (p == NULL) {
|
||||
tCC* pzName = pOpts->pzProgName;
|
||||
if (pzName == NULL) {
|
||||
pzName = pOpts->pzPROGNAME;
|
||||
if (pzName == NULL)
|
||||
pzName = zNil;
|
||||
}
|
||||
fprintf(stderr, zNoState, pzName);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pOpts->pSavedState = NULL;
|
||||
optionFree(pOpts);
|
||||
|
||||
memcpy(pOpts, p, sizeof(*p));
|
||||
memcpy(pOpts->pOptDesc, p+1, p->optCt * sizeof(tOptDesc));
|
||||
pOpts->pSavedState = p;
|
||||
|
||||
fixupSavedOptionArgs(pOpts);
|
||||
}
|
||||
|
||||
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
||||
|
||||
/*=export_func optionFree
|
||||
*
|
||||
* what: free allocated option processing memory
|
||||
* arg: tOptions*, pOpts, program options descriptor
|
||||
*
|
||||
* doc: AutoOpts sometimes allocates memory and puts pointers to it in the
|
||||
* option state structures. This routine deallocates all such memory.
|
||||
*
|
||||
* err: As long as memory has not been corrupted,
|
||||
* this routine is always successful.
|
||||
=*/
|
||||
void
|
||||
optionFree(tOptions* pOpts)
|
||||
{
|
||||
free_saved_state:
|
||||
{
|
||||
tOptDesc* p = pOpts->pOptDesc;
|
||||
int ct = pOpts->optCt;
|
||||
do {
|
||||
if (p->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(p->optArg.argString);
|
||||
p->optArg.argString = NULL;
|
||||
p->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
switch (OPTST_GET_ARGTYPE(p->fOptState)) {
|
||||
case OPARG_TYPE_STRING:
|
||||
#ifdef WITH_LIBREGEX
|
||||
if ( (p->fOptState & OPTST_STACKED)
|
||||
&& (p->optCookie != NULL)) {
|
||||
p->optArg.argString = ".*";
|
||||
optionUnstackArg(pOpts, p);
|
||||
}
|
||||
#else
|
||||
/* leak memory */;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_HIERARCHY:
|
||||
if (p->optCookie != NULL)
|
||||
unload_arg_list(p->optCookie);
|
||||
break;
|
||||
}
|
||||
|
||||
p->optCookie = NULL;
|
||||
} while (p++, --ct > 0);
|
||||
}
|
||||
if (pOpts->pSavedState != NULL) {
|
||||
tOptions * p = (tOptions*)pOpts->pSavedState;
|
||||
memcpy(pOpts, p, sizeof(*p));
|
||||
memcpy(pOpts->pOptDesc, p+1, p->optCt * sizeof(tOptDesc));
|
||||
AGFREE(pOpts->pSavedState);
|
||||
pOpts->pSavedState = NULL;
|
||||
goto free_saved_state;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/restore.c */
|
||||
+768
@@ -0,0 +1,768 @@
|
||||
|
||||
/*
|
||||
* \file save.c
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:15:19 bkorb"
|
||||
*
|
||||
* This module's routines will take the currently set options and
|
||||
* store them into an ".rc" file for re-interpretation the next
|
||||
* time the invoking program is run.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static char const *
|
||||
find_dir_name(tOptions * pOpts, int * p_free);
|
||||
|
||||
static char const *
|
||||
find_file_name(tOptions * pOpts, int * p_free_name);
|
||||
|
||||
static void
|
||||
prt_entry(FILE * fp, tOptDesc * p, char const * pzLA);
|
||||
|
||||
static void
|
||||
prt_value(FILE * fp, int depth, tOptDesc * pOD, tOptionValue const * ovp);
|
||||
|
||||
static void
|
||||
prt_string(FILE * fp, char const * name, char const * pz);
|
||||
|
||||
static void
|
||||
prt_val_list(FILE * fp, char const * name, tArgList * al);
|
||||
|
||||
static void
|
||||
prt_nested(FILE * fp, tOptDesc * p);
|
||||
|
||||
static FILE *
|
||||
open_sv_file(tOptions* pOpts);
|
||||
|
||||
static void
|
||||
prt_no_arg_opt(FILE * fp, tOptDesc * p, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
prt_str_arg(FILE * fp, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
prt_enum_arg(FILE * fp, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
prt_set_arg(FILE * fp, tOptDesc * pOD);
|
||||
|
||||
static void
|
||||
prt_file_arg(FILE * fp, tOptDesc * pOD, tOptions* pOpts);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
static char const *
|
||||
find_dir_name(tOptions * pOpts, int * p_free)
|
||||
{
|
||||
char const * pzDir;
|
||||
|
||||
if ( (pOpts->specOptIdx.save_opts == NO_EQUIVALENT)
|
||||
|| (pOpts->specOptIdx.save_opts == 0))
|
||||
return NULL;
|
||||
|
||||
pzDir = pOpts->pOptDesc[ pOpts->specOptIdx.save_opts ].optArg.argString;
|
||||
if ((pzDir != NULL) && (*pzDir != NUL))
|
||||
return pzDir;
|
||||
|
||||
/*
|
||||
* This function only works if there is a directory where
|
||||
* we can stash the RC (INI) file.
|
||||
*/
|
||||
{
|
||||
char const * const* papz = pOpts->papzHomeList;
|
||||
if (papz == NULL)
|
||||
return NULL;
|
||||
|
||||
while (papz[1] != NULL) papz++;
|
||||
pzDir = *papz;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF it does not require deciphering an env value, then just copy it
|
||||
*/
|
||||
if (*pzDir != '$')
|
||||
return pzDir;
|
||||
|
||||
{
|
||||
char const * pzEndDir = strchr(++pzDir, DIRCH);
|
||||
char * pzFileName;
|
||||
char * pzEnv;
|
||||
|
||||
if (pzEndDir != NULL) {
|
||||
char z[ AO_NAME_SIZE ];
|
||||
if ((pzEndDir - pzDir) > AO_NAME_LIMIT )
|
||||
return NULL;
|
||||
memcpy(z, pzDir, (size_t)(pzEndDir - pzDir));
|
||||
z[pzEndDir - pzDir] = NUL;
|
||||
pzEnv = getenv(z);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Make sure we can get the env value (after stripping off
|
||||
* any trailing directory or file names)
|
||||
*/
|
||||
pzEnv = getenv(pzDir);
|
||||
}
|
||||
|
||||
if (pzEnv == NULL) {
|
||||
fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
|
||||
fprintf(stderr, zNotDef, pzDir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pzEndDir == NULL)
|
||||
return pzEnv;
|
||||
|
||||
{
|
||||
size_t sz = strlen(pzEnv) + strlen(pzEndDir) + 2;
|
||||
pzFileName = (char*)AGALOC(sz, "dir name");
|
||||
}
|
||||
|
||||
if (pzFileName == NULL)
|
||||
return NULL;
|
||||
|
||||
*p_free = 1;
|
||||
/*
|
||||
* Glue together the full name into the allocated memory.
|
||||
* FIXME: We lose track of this memory.
|
||||
*/
|
||||
sprintf(pzFileName, "%s/%s", pzEnv, pzEndDir);
|
||||
return pzFileName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char const *
|
||||
find_file_name(tOptions * pOpts, int * p_free_name)
|
||||
{
|
||||
struct stat stBuf;
|
||||
int free_dir_name = 0;
|
||||
|
||||
char const * pzDir = find_dir_name(pOpts, &free_dir_name);
|
||||
if (pzDir == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* See if we can find the specified directory. We use a once-only loop
|
||||
* structure so we can bail out early.
|
||||
*/
|
||||
if (stat(pzDir, &stBuf) != 0) do {
|
||||
char z[AG_PATH_MAX];
|
||||
char * dirchp;
|
||||
|
||||
/*
|
||||
* IF we could not, check to see if we got a full
|
||||
* path to a file name that has not been created yet.
|
||||
*/
|
||||
if (errno != ENOENT) {
|
||||
bogus_name:
|
||||
fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
|
||||
fprintf(stderr, zNoStat, errno, strerror(errno), pzDir);
|
||||
if (free_dir_name)
|
||||
AGFREE((void*)pzDir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Strip off the last component, stat the remaining string and
|
||||
* that string must name a directory
|
||||
*/
|
||||
dirchp = strrchr(pzDir, DIRCH);
|
||||
if (dirchp == NULL) {
|
||||
stBuf.st_mode = S_IFREG;
|
||||
break; /* found directory -- viz., "." */
|
||||
}
|
||||
|
||||
if ((size_t)(dirchp - pzDir) >= sizeof(z))
|
||||
goto bogus_name;
|
||||
|
||||
memcpy(z, pzDir, (size_t)(dirchp - pzDir));
|
||||
z[dirchp - pzDir] = NUL;
|
||||
|
||||
if ((stat(z, &stBuf) != 0) || ! S_ISDIR(stBuf.st_mode))
|
||||
goto bogus_name;
|
||||
stBuf.st_mode = S_IFREG; /* file within this directory */
|
||||
} while (false);
|
||||
|
||||
/*
|
||||
* IF what we found was a directory,
|
||||
* THEN tack on the config file name
|
||||
*/
|
||||
if (S_ISDIR(stBuf.st_mode)) {
|
||||
size_t sz = strlen(pzDir) + strlen(pOpts->pzRcName) + 2;
|
||||
|
||||
{
|
||||
char * pzPath = (char*)AGALOC(sz, "file name");
|
||||
#ifdef HAVE_SNPRINTF
|
||||
snprintf(pzPath, sz, "%s/%s", pzDir, pOpts->pzRcName);
|
||||
#else
|
||||
sprintf(pzPath, "%s/%s", pzDir, pOpts->pzRcName);
|
||||
#endif
|
||||
if (free_dir_name)
|
||||
AGFREE((void*)pzDir);
|
||||
pzDir = pzPath;
|
||||
free_dir_name = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF we cannot stat the object for any reason other than
|
||||
* it does not exist, then we bail out
|
||||
*/
|
||||
if (stat(pzDir, &stBuf) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
|
||||
fprintf(stderr, zNoStat, errno, strerror(errno),
|
||||
pzDir);
|
||||
AGFREE((void*)pzDir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* It does not exist yet, but it will be a regular file
|
||||
*/
|
||||
stBuf.st_mode = S_IFREG;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that whatever we ultimately found, that it either is
|
||||
* or will soon be a file.
|
||||
*/
|
||||
if (! S_ISREG(stBuf.st_mode)) {
|
||||
fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
|
||||
fprintf(stderr, zNotFile, pzDir);
|
||||
if (free_dir_name)
|
||||
AGFREE((void*)pzDir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get rid of the old file
|
||||
*/
|
||||
unlink(pzDir);
|
||||
*p_free_name = free_dir_name;
|
||||
return pzDir;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prt_entry(FILE * fp, tOptDesc * p, char const * pzLA)
|
||||
{
|
||||
/*
|
||||
* There is an argument. Pad the name so values line up.
|
||||
* Not disabled *OR* this got equivalenced to another opt,
|
||||
* then use current option name.
|
||||
* Otherwise, there must be a disablement name.
|
||||
*/
|
||||
{
|
||||
char const * pz;
|
||||
if (! DISABLED_OPT(p) || (p->optEquivIndex != NO_EQUIVALENT))
|
||||
pz = p->pz_Name;
|
||||
else
|
||||
pz = p->pz_DisableName;
|
||||
|
||||
fprintf(fp, "%-18s", pz);
|
||||
}
|
||||
/*
|
||||
* IF the option is numeric only,
|
||||
* THEN the char pointer is really the number
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(p->fOptState) == OPARG_TYPE_NUMERIC)
|
||||
fprintf(fp, " %d\n", (int)(t_word)pzLA);
|
||||
|
||||
/*
|
||||
* OTHERWISE, FOR each line of the value text, ...
|
||||
*/
|
||||
else if (pzLA == NULL)
|
||||
fputc(NL, fp);
|
||||
|
||||
else {
|
||||
fputc(' ', fp); fputc(' ', fp);
|
||||
for (;;) {
|
||||
char const * pzNl = strchr(pzLA, NL);
|
||||
|
||||
/*
|
||||
* IF this is the last line
|
||||
* THEN bail and print it
|
||||
*/
|
||||
if (pzNl == NULL)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Print the continuation and the text from the current line
|
||||
*/
|
||||
(void)fwrite(pzLA, (size_t)(pzNl - pzLA), (size_t)1, fp);
|
||||
pzLA = pzNl+1; /* advance the Last Arg pointer */
|
||||
fputs("\\\n", fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Terminate the entry
|
||||
*/
|
||||
fputs(pzLA, fp);
|
||||
fputc(NL, fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prt_value(FILE * fp, int depth, tOptDesc * pOD, tOptionValue const * ovp)
|
||||
{
|
||||
while (--depth >= 0)
|
||||
putc(' ', fp), putc(' ', fp);
|
||||
|
||||
switch (ovp->valType) {
|
||||
default:
|
||||
case OPARG_TYPE_NONE:
|
||||
fprintf(fp, NULL_ATR_FMT, ovp->pzName);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_STRING:
|
||||
prt_string(fp, ovp->pzName, ovp->v.strVal);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_ENUMERATION:
|
||||
case OPARG_TYPE_MEMBERSHIP:
|
||||
if (pOD != NULL) {
|
||||
tAoUI opt_state = pOD->fOptState;
|
||||
uintptr_t val = pOD->optArg.argEnum;
|
||||
char const * typ = (ovp->valType == OPARG_TYPE_ENUMERATION)
|
||||
? "keyword" : "set-membership";
|
||||
|
||||
fprintf(fp, TYPE_ATR_FMT, ovp->pzName, typ);
|
||||
|
||||
/*
|
||||
* This is a magic incantation that will convert the
|
||||
* bit flag values back into a string suitable for printing.
|
||||
*/
|
||||
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD );
|
||||
if (pOD->optArg.argString != NULL) {
|
||||
fputs(pOD->optArg.argString, fp);
|
||||
|
||||
if (ovp->valType != OPARG_TYPE_ENUMERATION) {
|
||||
/*
|
||||
* set membership strings get allocated
|
||||
*/
|
||||
AGFREE((void*)pOD->optArg.argString);
|
||||
}
|
||||
}
|
||||
|
||||
pOD->optArg.argEnum = val;
|
||||
pOD->fOptState = opt_state;
|
||||
fprintf(fp, END_XML_FMT, ovp->pzName);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case OPARG_TYPE_NUMERIC:
|
||||
fprintf(fp, NUMB_ATR_FMT, ovp->pzName, ovp->v.longVal);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_BOOLEAN:
|
||||
fprintf(fp, BOOL_ATR_FMT, ovp->pzName,
|
||||
ovp->v.boolVal ? "true" : "false");
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_HIERARCHY:
|
||||
prt_val_list(fp, ovp->pzName, ovp->v.nestVal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prt_string(FILE * fp, char const * name, char const * pz)
|
||||
{
|
||||
fprintf(fp, OPEN_XML_FMT, name);
|
||||
for (;;) {
|
||||
int ch = ((int)*(pz++)) & 0xFF;
|
||||
|
||||
switch (ch) {
|
||||
case NUL: goto string_done;
|
||||
|
||||
case '&':
|
||||
case '<':
|
||||
case '>':
|
||||
#if __GNUC__ >= 4
|
||||
case 1 ... (' ' - 1):
|
||||
case ('~' + 1) ... 0xFF:
|
||||
#endif
|
||||
emit_special_char(fp, ch);
|
||||
break;
|
||||
|
||||
default:
|
||||
#if __GNUC__ < 4
|
||||
if ( ((ch >= 1) && (ch <= (' ' - 1)))
|
||||
|| ((ch >= ('~' + 1)) && (ch <= 0xFF)) ) {
|
||||
emit_special_char(fp, ch);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
putc(ch, fp);
|
||||
}
|
||||
} string_done:;
|
||||
fprintf(fp, END_XML_FMT, name);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prt_val_list(FILE * fp, char const * name, tArgList * al)
|
||||
{
|
||||
static int depth = 1;
|
||||
|
||||
int sp_ct;
|
||||
int opt_ct;
|
||||
void ** opt_list;
|
||||
|
||||
if (al == NULL)
|
||||
return;
|
||||
opt_ct = al->useCt;
|
||||
opt_list = (void **)al->apzArgs;
|
||||
|
||||
if (opt_ct <= 0) {
|
||||
fprintf(fp, OPEN_CLOSE_FMT, name);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, NESTED_OPT_FMT, name);
|
||||
|
||||
depth++;
|
||||
while (--opt_ct >= 0) {
|
||||
tOptionValue const * ovp = *(opt_list++);
|
||||
|
||||
prt_value(fp, depth, NULL, ovp);
|
||||
}
|
||||
depth--;
|
||||
|
||||
for (sp_ct = depth; --sp_ct >= 0;)
|
||||
putc(' ', fp), putc(' ', fp);
|
||||
fprintf(fp, "</%s>\n", name);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prt_nested(FILE * fp, tOptDesc * p)
|
||||
{
|
||||
int opt_ct;
|
||||
tArgList * al = p->optCookie;
|
||||
void ** opt_list;
|
||||
|
||||
if (al == NULL)
|
||||
return;
|
||||
|
||||
opt_ct = al->useCt;
|
||||
opt_list = (void **)al->apzArgs;
|
||||
|
||||
if (opt_ct <= 0)
|
||||
return;
|
||||
|
||||
do {
|
||||
tOptionValue const * base = *(opt_list++);
|
||||
tOptionValue const * ovp = optionGetValue(base, NULL);
|
||||
|
||||
if (ovp == NULL)
|
||||
continue;
|
||||
|
||||
fprintf(fp, NESTED_OPT_FMT, p->pz_Name);
|
||||
|
||||
do {
|
||||
prt_value(fp, 1, p, ovp);
|
||||
|
||||
} while (ovp = optionNextValue(base, ovp),
|
||||
ovp != NULL);
|
||||
|
||||
fprintf(fp, "</%s>\n", p->pz_Name);
|
||||
} while (--opt_ct > 0);
|
||||
}
|
||||
|
||||
|
||||
static FILE *
|
||||
open_sv_file(tOptions* pOpts)
|
||||
{
|
||||
FILE * fp;
|
||||
|
||||
{
|
||||
int free_name = 0;
|
||||
char const * pzFName = find_file_name(pOpts, &free_name);
|
||||
if (pzFName == NULL)
|
||||
return NULL;
|
||||
|
||||
fp = fopen(pzFName, "w" FOPEN_BINARY_FLAG);
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
|
||||
fprintf(stderr, zNoCreat, errno, strerror(errno), pzFName);
|
||||
if (free_name)
|
||||
AGFREE((void*) pzFName );
|
||||
return fp;
|
||||
}
|
||||
|
||||
if (free_name)
|
||||
AGFREE((void*)pzFName);
|
||||
}
|
||||
|
||||
{
|
||||
char const * pz = pOpts->pzUsageTitle;
|
||||
fputs("# ", fp);
|
||||
do { fputc(*pz, fp); } while (*(pz++) != NL);
|
||||
}
|
||||
|
||||
{
|
||||
time_t timeVal = time(NULL);
|
||||
char * pzTime = ctime(&timeVal);
|
||||
|
||||
fprintf(fp, zPresetFile, pzTime);
|
||||
#ifdef HAVE_ALLOCATED_CTIME
|
||||
/*
|
||||
* The return values for ctime(), localtime(), and gmtime()
|
||||
* normally point to static data that is overwritten by each call.
|
||||
* The test to detect allocated ctime, so we leak the memory.
|
||||
*/
|
||||
AGFREE((void*)pzTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
static void
|
||||
prt_no_arg_opt(FILE * fp, tOptDesc * p, tOptDesc * pOD)
|
||||
{
|
||||
/*
|
||||
* The aliased to argument indicates whether or not the option
|
||||
* is "disabled". However, the original option has the name
|
||||
* string, so we get that there, not with "p".
|
||||
*/
|
||||
char const * pznm =
|
||||
(DISABLED_OPT(p)) ? pOD->pz_DisableName : pOD->pz_Name;
|
||||
/*
|
||||
* If the option was disabled and the disablement name is NULL,
|
||||
* then the disablement was caused by aliasing.
|
||||
* Use the name as the string to emit.
|
||||
*/
|
||||
if (pznm == NULL)
|
||||
pznm = pOD->pz_Name;
|
||||
|
||||
fprintf(fp, "%s\n", pznm);
|
||||
}
|
||||
|
||||
static void
|
||||
prt_str_arg(FILE * fp, tOptDesc * pOD)
|
||||
{
|
||||
if (pOD->fOptState & OPTST_STACKED) {
|
||||
tArgList * pAL = (tArgList*)pOD->optCookie;
|
||||
int uct = pAL->useCt;
|
||||
char const ** ppz = pAL->apzArgs;
|
||||
|
||||
/*
|
||||
* un-disable multiple copies of disabled options.
|
||||
*/
|
||||
if (uct > 1)
|
||||
pOD->fOptState &= ~OPTST_DISABLED;
|
||||
|
||||
while (uct-- > 0)
|
||||
prt_entry(fp, pOD, *(ppz++));
|
||||
} else {
|
||||
prt_entry(fp, pOD, pOD->optArg.argString);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prt_enum_arg(FILE * fp, tOptDesc * pOD)
|
||||
{
|
||||
uintptr_t val = pOD->optArg.argEnum;
|
||||
|
||||
/*
|
||||
* This is a magic incantation that will convert the
|
||||
* bit flag values back into a string suitable for printing.
|
||||
*/
|
||||
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
|
||||
prt_entry(fp, pOD, (void*)(pOD->optArg.argString));
|
||||
|
||||
pOD->optArg.argEnum = val;
|
||||
}
|
||||
|
||||
static void
|
||||
prt_set_arg(FILE * fp, tOptDesc * pOD)
|
||||
{
|
||||
uintptr_t val = pOD->optArg.argEnum;
|
||||
|
||||
/*
|
||||
* This is a magic incantation that will convert the
|
||||
* bit flag values back into a string suitable for printing.
|
||||
*/
|
||||
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
|
||||
prt_entry(fp, pOD, (void*)(pOD->optArg.argString));
|
||||
|
||||
if (pOD->optArg.argString != NULL) {
|
||||
/*
|
||||
* set membership strings get allocated
|
||||
*/
|
||||
AGFREE((void*)pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
pOD->optArg.argEnum = val;
|
||||
}
|
||||
|
||||
static void
|
||||
prt_file_arg(FILE * fp, tOptDesc * pOD, tOptions* pOpts)
|
||||
{
|
||||
/*
|
||||
* If the cookie is not NULL, then it has the file name, period.
|
||||
* Otherwise, if we have a non-NULL string argument, then....
|
||||
*/
|
||||
if (pOD->optCookie != NULL)
|
||||
prt_entry(fp, pOD, pOD->optCookie);
|
||||
|
||||
else if (HAS_originalOptArgArray(pOpts)) {
|
||||
char const * orig =
|
||||
pOpts->originalOptArgArray[pOD->optIndex].argString;
|
||||
|
||||
if (pOD->optArg.argString == orig)
|
||||
return;
|
||||
|
||||
prt_entry(fp, pOD, pOD->optArg.argString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionSaveFile
|
||||
*
|
||||
* what: saves the option state to a file
|
||||
*
|
||||
* arg: tOptions*, pOpts, program options descriptor
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This routine will save the state of option processing to a file. The name
|
||||
* of that file can be specified with the argument to the @code{--save-opts}
|
||||
* option, or by appending the @code{rcfile} attribute to the last
|
||||
* @code{homerc} attribute. If no @code{rcfile} attribute was specified, it
|
||||
* will default to @code{.@i{programname}rc}. If you wish to specify another
|
||||
* file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro.
|
||||
*
|
||||
* The recommend usage is as follows:
|
||||
* @example
|
||||
* optionProcess(&progOptions, argc, argv);
|
||||
* if (i_want_a_non_standard_place_for_this)
|
||||
* SET_OPT_SAVE_OPTS("myfilename");
|
||||
* optionSaveFile(&progOptions);
|
||||
* @end example
|
||||
*
|
||||
* err:
|
||||
*
|
||||
* If no @code{homerc} file was specified, this routine will silently return
|
||||
* and do nothing. If the output file cannot be created or updated, a message
|
||||
* will be printed to @code{stderr} and the routine will return.
|
||||
=*/
|
||||
void
|
||||
optionSaveFile(tOptions* pOpts)
|
||||
{
|
||||
tOptDesc* pOD;
|
||||
int ct;
|
||||
FILE * fp = open_sv_file(pOpts);
|
||||
|
||||
if (fp == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* FOR each of the defined options, ...
|
||||
*/
|
||||
ct = pOpts->presetOptCt;
|
||||
pOD = pOpts->pOptDesc;
|
||||
do {
|
||||
tOptDesc * p;
|
||||
|
||||
/*
|
||||
* IF the option has not been defined
|
||||
* OR it does not take an initialization value
|
||||
* OR it is equivalenced to another option
|
||||
* THEN continue (ignore it)
|
||||
*
|
||||
* Equivalenced options get picked up when the equivalenced-to
|
||||
* option is processed.
|
||||
*/
|
||||
if (UNUSED_OPT(pOD))
|
||||
continue;
|
||||
|
||||
if ((pOD->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0)
|
||||
continue;
|
||||
|
||||
if ( (pOD->optEquivIndex != NO_EQUIVALENT)
|
||||
&& (pOD->optEquivIndex != pOD->optIndex))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The option argument data are found at the equivalenced-to option,
|
||||
* but the actual option argument type comes from the original
|
||||
* option descriptor. Be careful!
|
||||
*/
|
||||
p = ((pOD->fOptState & OPTST_EQUIVALENCE) != 0)
|
||||
? (pOpts->pOptDesc + pOD->optActualIndex) : pOD;
|
||||
|
||||
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
|
||||
case OPARG_TYPE_NONE:
|
||||
prt_no_arg_opt(fp, p, pOD);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_NUMERIC:
|
||||
prt_entry(fp, p, (void*)(p->optArg.argInt));
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_STRING:
|
||||
prt_str_arg(fp, p);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_ENUMERATION:
|
||||
prt_enum_arg(fp, p);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_MEMBERSHIP:
|
||||
prt_set_arg(fp, p);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_BOOLEAN:
|
||||
prt_entry(fp, p, p->optArg.argBool ? "true" : "false");
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_HIERARCHY:
|
||||
prt_nested(fp, p);
|
||||
break;
|
||||
|
||||
case OPARG_TYPE_FILE:
|
||||
prt_file_arg(fp, p, pOpts);
|
||||
break;
|
||||
|
||||
default:
|
||||
break; /* cannot handle - skip it */
|
||||
}
|
||||
} while (pOD++, (--ct > 0));
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/save.c */
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
|
||||
/*
|
||||
* \file sort.c
|
||||
*
|
||||
* Time-stamp: "2011-05-24 18:07:14 bkorb"
|
||||
*
|
||||
* This module implements argument sorting.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static tSuccess
|
||||
mustHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
|
||||
char** ppzOpts, int* pOptsIdx);
|
||||
|
||||
static tSuccess
|
||||
mayHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
|
||||
char** ppzOpts, int* pOptsIdx);
|
||||
|
||||
static tSuccess
|
||||
checkShortOpts(tOptions* pOpts, char* pzArg, tOptState* pOS,
|
||||
char** ppzOpts, int* pOptsIdx);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
/*
|
||||
* "mustHandleArg" and "mayHandleArg" are really similar. The biggest
|
||||
* difference is that "may" will consume the next argument only if it
|
||||
* does not start with a hyphen and "must" will consume it, hyphen or not.
|
||||
*/
|
||||
static tSuccess
|
||||
mustHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
|
||||
char** ppzOpts, int* pOptsIdx)
|
||||
{
|
||||
/*
|
||||
* An option argument is required. Long options can either have
|
||||
* a separate command line argument, or an argument attached by
|
||||
* the '=' character. Figure out which.
|
||||
*/
|
||||
switch (pOS->optType) {
|
||||
case TOPT_SHORT:
|
||||
/*
|
||||
* See if an arg string follows the flag character. If not,
|
||||
* the next arg must be the option argument.
|
||||
*/
|
||||
if (*pzArg != NUL)
|
||||
return SUCCESS;
|
||||
break;
|
||||
|
||||
case TOPT_LONG:
|
||||
/*
|
||||
* See if an arg string has already been assigned (glued on
|
||||
* with an `=' character). If not, the next is the opt arg.
|
||||
*/
|
||||
if (pOS->pzOptArg != NULL)
|
||||
return SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
if (pOpts->curOptIdx >= pOpts->origArgCt)
|
||||
return FAILURE;
|
||||
|
||||
ppzOpts[ (*pOptsIdx)++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static tSuccess
|
||||
mayHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
|
||||
char** ppzOpts, int* pOptsIdx)
|
||||
{
|
||||
/*
|
||||
* An option argument is optional.
|
||||
*/
|
||||
switch (pOS->optType) {
|
||||
case TOPT_SHORT:
|
||||
/*
|
||||
* IF nothing is glued on after the current flag character,
|
||||
* THEN see if there is another argument. If so and if it
|
||||
* does *NOT* start with a hyphen, then it is the option arg.
|
||||
*/
|
||||
if (*pzArg != NUL)
|
||||
return SUCCESS;
|
||||
break;
|
||||
|
||||
case TOPT_LONG:
|
||||
/*
|
||||
* Look for an argument if we don't already have one (glued on
|
||||
* with a `=' character)
|
||||
*/
|
||||
if (pOS->pzOptArg != NULL)
|
||||
return SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
if (pOpts->curOptIdx >= pOpts->origArgCt)
|
||||
return PROBLEM;
|
||||
|
||||
pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
|
||||
if (*pzArg != '-')
|
||||
ppzOpts[ (*pOptsIdx)++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a string of short options glued together. If the last one
|
||||
* does or may take an argument, the do the argument processing and leave.
|
||||
*/
|
||||
static tSuccess
|
||||
checkShortOpts(tOptions* pOpts, char* pzArg, tOptState* pOS,
|
||||
char** ppzOpts, int* pOptsIdx)
|
||||
{
|
||||
while (*pzArg != NUL) {
|
||||
if (FAILED(opt_find_short(pOpts, (tAoUC)*pzArg, pOS)))
|
||||
return FAILURE;
|
||||
|
||||
/*
|
||||
* See if we can have an arg.
|
||||
*/
|
||||
if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
|
||||
pzArg++;
|
||||
|
||||
} else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) {
|
||||
/*
|
||||
* Take an argument if it is not attached and it does not
|
||||
* start with a hyphen.
|
||||
*/
|
||||
if (pzArg[1] != NUL)
|
||||
return SUCCESS;
|
||||
|
||||
pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
|
||||
if (*pzArg != '-')
|
||||
ppzOpts[ (*pOptsIdx)++ ] =
|
||||
pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
return SUCCESS;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* IF we need another argument, be sure it is there and
|
||||
* take it.
|
||||
*/
|
||||
if (pzArg[1] == NUL) {
|
||||
if (pOpts->curOptIdx >= pOpts->origArgCt)
|
||||
return FAILURE;
|
||||
ppzOpts[ (*pOptsIdx)++ ] =
|
||||
pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the program wants sorted options (separated operands and options),
|
||||
* then this routine will to the trick.
|
||||
*/
|
||||
LOCAL void
|
||||
optionSort(tOptions* pOpts)
|
||||
{
|
||||
char** ppzOpts;
|
||||
char** ppzOpds;
|
||||
int optsIdx = 0;
|
||||
int opdsIdx = 0;
|
||||
|
||||
tOptState os = OPTSTATE_INITIALIZER(DEFINED);
|
||||
|
||||
/*
|
||||
* Disable for POSIX conformance, or if there are no operands.
|
||||
*/
|
||||
if ( (getenv("POSIXLY_CORRECT") != NULL)
|
||||
|| NAMED_OPTS(pOpts))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Make sure we can allocate two full-sized arg vectors.
|
||||
*/
|
||||
ppzOpts = malloc(pOpts->origArgCt * sizeof(char*));
|
||||
if (ppzOpts == NULL)
|
||||
goto exit_no_mem;
|
||||
|
||||
ppzOpds = malloc(pOpts->origArgCt * sizeof(char*));
|
||||
if (ppzOpds == NULL) {
|
||||
free(ppzOpts);
|
||||
goto exit_no_mem;
|
||||
}
|
||||
|
||||
pOpts->curOptIdx = 1;
|
||||
pOpts->pzCurOpt = NULL;
|
||||
|
||||
/*
|
||||
* Now, process all the options from our current position onward.
|
||||
* (This allows interspersed options and arguments for the few
|
||||
* non-standard programs that require it.)
|
||||
*/
|
||||
for (;;) {
|
||||
char* pzArg;
|
||||
tSuccess res;
|
||||
|
||||
/*
|
||||
* If we're out of arguments, we're done. Join the option and
|
||||
* operand lists into the original argument vector.
|
||||
*/
|
||||
if (pOpts->curOptIdx >= pOpts->origArgCt) {
|
||||
errno = 0;
|
||||
goto joinLists;
|
||||
}
|
||||
|
||||
pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
|
||||
if (*pzArg != '-') {
|
||||
ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (pzArg[1]) {
|
||||
case NUL:
|
||||
/*
|
||||
* A single hyphen is an operand.
|
||||
*/
|
||||
ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
continue;
|
||||
|
||||
case '-':
|
||||
/*
|
||||
* Two consecutive hypens. Put them on the options list and then
|
||||
* _always_ force the remainder of the arguments to be operands.
|
||||
*/
|
||||
if (pzArg[2] == NUL) {
|
||||
ppzOpts[ optsIdx++ ] =
|
||||
pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
goto restOperands;
|
||||
}
|
||||
res = opt_find_long(pOpts, pzArg+2, &os);
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* If short options are not allowed, then do long
|
||||
* option processing. Otherwise the character must be a
|
||||
* short (i.e. single character) option.
|
||||
*/
|
||||
if ((pOpts->fOptSet & OPTPROC_SHORTOPT) == 0) {
|
||||
res = opt_find_long(pOpts, pzArg+1, &os);
|
||||
} else {
|
||||
res = opt_find_short(pOpts, (tAoUC)pzArg[1], &os);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (FAILED(res)) {
|
||||
errno = EINVAL;
|
||||
goto freeTemps;
|
||||
}
|
||||
|
||||
/*
|
||||
* We've found an option. Add the argument to the option list.
|
||||
* Next, we have to see if we need to pull another argument to be
|
||||
* used as the option argument.
|
||||
*/
|
||||
ppzOpts[ optsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
|
||||
if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) {
|
||||
/*
|
||||
* No option argument. If we have a short option here,
|
||||
* then scan for short options until we get to the end
|
||||
* of the argument string.
|
||||
*/
|
||||
if ( (os.optType == TOPT_SHORT)
|
||||
&& FAILED(checkShortOpts(pOpts, pzArg+2, &os, ppzOpts,
|
||||
&optsIdx)) ) {
|
||||
errno = EINVAL;
|
||||
goto freeTemps;
|
||||
}
|
||||
|
||||
} else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) {
|
||||
switch (mayHandleArg(pOpts, pzArg+2, &os, ppzOpts, &optsIdx)) {
|
||||
case FAILURE: errno = EIO; goto freeTemps;
|
||||
case PROBLEM: errno = 0; goto joinLists;
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (mustHandleArg(pOpts, pzArg+2, &os, ppzOpts, &optsIdx)) {
|
||||
case PROBLEM:
|
||||
case FAILURE: errno = EIO; goto freeTemps;
|
||||
}
|
||||
}
|
||||
} /* for (;;) */
|
||||
|
||||
restOperands:
|
||||
while (pOpts->curOptIdx < pOpts->origArgCt)
|
||||
ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
|
||||
|
||||
joinLists:
|
||||
if (optsIdx > 0)
|
||||
memcpy(pOpts->origArgVect + 1, ppzOpts, optsIdx * sizeof(char*));
|
||||
if (opdsIdx > 0)
|
||||
memcpy(pOpts->origArgVect + 1 + optsIdx, ppzOpds,
|
||||
opdsIdx * sizeof(char*));
|
||||
|
||||
freeTemps:
|
||||
free(ppzOpts);
|
||||
free(ppzOpds);
|
||||
return;
|
||||
|
||||
exit_no_mem:
|
||||
errno = ENOMEM;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/sort.c */
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
|
||||
/**
|
||||
* \file stack.c
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:16:41 bkorb"
|
||||
*
|
||||
* This is a special option processing routine that will save the
|
||||
* argument to an option in a FIFO queue.
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
#ifdef WITH_LIBREGEX
|
||||
# include REGEX_HEADER
|
||||
#endif
|
||||
|
||||
/*=export_func optionUnstackArg
|
||||
* private:
|
||||
*
|
||||
* what: Remove option args from a stack
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Invoked for options that are equivalenced to stacked options.
|
||||
=*/
|
||||
void
|
||||
optionUnstackArg(tOptions * pOpts, tOptDesc * pOptDesc)
|
||||
{
|
||||
tArgList * pAL;
|
||||
|
||||
(void)pOpts;
|
||||
|
||||
if ((pOptDesc->fOptState & OPTST_RESET) != 0)
|
||||
return;
|
||||
pAL = (tArgList*)pOptDesc->optCookie;
|
||||
|
||||
/*
|
||||
* IF we don't have any stacked options,
|
||||
* THEN indicate that we don't have any of these options
|
||||
*/
|
||||
if (pAL == NULL) {
|
||||
pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0)
|
||||
pOptDesc->fOptState |= OPTST_DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_LIBREGEX
|
||||
{
|
||||
regex_t re;
|
||||
int i, ct, dIdx;
|
||||
|
||||
if (regcomp(&re, pOptDesc->optArg.argString, REG_NOSUB) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* search the list for the entry(s) to remove. Entries that
|
||||
* are removed are *not* copied into the result. The source
|
||||
* index is incremented every time. The destination only when
|
||||
* we are keeping a define.
|
||||
*/
|
||||
for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
|
||||
char const * pzSrc = pAL->apzArgs[ i ];
|
||||
char * pzEq = strchr(pzSrc, '=');
|
||||
int res;
|
||||
|
||||
|
||||
if (pzEq != NULL)
|
||||
*pzEq = NUL;
|
||||
|
||||
res = regexec(&re, pzSrc, (size_t)0, NULL, 0);
|
||||
switch (res) {
|
||||
case 0:
|
||||
/*
|
||||
* Remove this entry by reducing the in-use count
|
||||
* and *not* putting the string pointer back into
|
||||
* the list.
|
||||
*/
|
||||
AGFREE(pzSrc);
|
||||
pAL->useCt--;
|
||||
break;
|
||||
|
||||
default:
|
||||
case REG_NOMATCH:
|
||||
if (pzEq != NULL)
|
||||
*pzEq = '=';
|
||||
|
||||
/*
|
||||
* IF we have dropped an entry
|
||||
* THEN we have to move the current one.
|
||||
*/
|
||||
if (dIdx != i)
|
||||
pAL->apzArgs[ dIdx ] = pzSrc;
|
||||
dIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
regfree(&re);
|
||||
}
|
||||
#else /* not WITH_LIBREGEX */
|
||||
{
|
||||
int i, ct, dIdx;
|
||||
|
||||
/*
|
||||
* search the list for the entry(s) to remove. Entries that
|
||||
* are removed are *not* copied into the result. The source
|
||||
* index is incremented every time. The destination only when
|
||||
* we are keeping a define.
|
||||
*/
|
||||
for (i = 0, dIdx = 0, ct = pAL->useCt; --ct >= 0; i++) {
|
||||
tCC* pzSrc = pAL->apzArgs[ i ];
|
||||
char* pzEq = strchr(pzSrc, '=');
|
||||
|
||||
if (pzEq != NULL)
|
||||
*pzEq = NUL;
|
||||
|
||||
if (strcmp(pzSrc, pOptDesc->optArg.argString) == 0) {
|
||||
/*
|
||||
* Remove this entry by reducing the in-use count
|
||||
* and *not* putting the string pointer back into
|
||||
* the list.
|
||||
*/
|
||||
AGFREE(pzSrc);
|
||||
pAL->useCt--;
|
||||
} else {
|
||||
if (pzEq != NULL)
|
||||
*pzEq = '=';
|
||||
|
||||
/*
|
||||
* IF we have dropped an entry
|
||||
* THEN we have to move the current one.
|
||||
*/
|
||||
if (dIdx != i)
|
||||
pAL->apzArgs[ dIdx ] = pzSrc;
|
||||
dIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_LIBREGEX */
|
||||
/*
|
||||
* IF we have unstacked everything,
|
||||
* THEN indicate that we don't have any of these options
|
||||
*/
|
||||
if (pAL->useCt == 0) {
|
||||
pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
|
||||
if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0)
|
||||
pOptDesc->fOptState |= OPTST_DISABLED;
|
||||
AGFREE((void*)pAL);
|
||||
pOptDesc->optCookie = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Put an entry into an argument list. The first argument points to
|
||||
* a pointer to the argument list structure. It gets passed around
|
||||
* as an opaque address.
|
||||
*/
|
||||
LOCAL void
|
||||
addArgListEntry(void** ppAL, void* entry)
|
||||
{
|
||||
tArgList* pAL = *(void**)ppAL;
|
||||
|
||||
/*
|
||||
* IF we have never allocated one of these,
|
||||
* THEN allocate one now
|
||||
*/
|
||||
if (pAL == NULL) {
|
||||
pAL = (tArgList*)AGALOC(sizeof(*pAL), "new option arg stack");
|
||||
if (pAL == NULL)
|
||||
return;
|
||||
pAL->useCt = 0;
|
||||
pAL->allocCt = MIN_ARG_ALLOC_CT;
|
||||
*ppAL = (void*)pAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* ELSE if we are out of room
|
||||
* THEN make it bigger
|
||||
*/
|
||||
else if (pAL->useCt >= pAL->allocCt) {
|
||||
size_t sz = sizeof(*pAL);
|
||||
pAL->allocCt += INCR_ARG_ALLOC_CT;
|
||||
|
||||
/*
|
||||
* The base structure contains space for MIN_ARG_ALLOC_CT
|
||||
* pointers. We subtract it off to find our augment size.
|
||||
*/
|
||||
sz += sizeof(char*) * (pAL->allocCt - MIN_ARG_ALLOC_CT);
|
||||
pAL = (tArgList*)AGREALOC((void*)pAL, sz, "expanded opt arg stack");
|
||||
if (pAL == NULL)
|
||||
return;
|
||||
*ppAL = (void*)pAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the new argument into the list
|
||||
*/
|
||||
pAL->apzArgs[ (pAL->useCt)++ ] = entry;
|
||||
}
|
||||
|
||||
|
||||
/*=export_func optionStackArg
|
||||
* private:
|
||||
*
|
||||
* what: put option args on a stack
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Keep an entry-ordered list of option arguments.
|
||||
=*/
|
||||
void
|
||||
optionStackArg(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
char * pz;
|
||||
|
||||
(void)pOpts;
|
||||
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0) {
|
||||
tArgList* pAL = (void*)pOD->optCookie;
|
||||
int ix;
|
||||
if (pAL == NULL)
|
||||
return;
|
||||
|
||||
ix = pAL->useCt;
|
||||
while (--ix >= 0)
|
||||
AGFREE(pAL->apzArgs[ix]);
|
||||
AGFREE(pAL);
|
||||
|
||||
} else {
|
||||
if (pOD->optArg.argString == NULL)
|
||||
return;
|
||||
|
||||
AGDUPSTR(pz, pOD->optArg.argString, "stack arg");
|
||||
addArgListEntry(&(pOD->optCookie), (void*)pz);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/stack.c */
|
||||
@@ -0,0 +1,267 @@
|
||||
|
||||
/**
|
||||
* \file streqvcmp.c
|
||||
*
|
||||
* Time-stamp: "2012-03-31 13:17:39 bkorb"
|
||||
*
|
||||
* String Equivalence Comparison
|
||||
*
|
||||
* These routines allow any character to be mapped to any other
|
||||
* character before comparison. In processing long option names,
|
||||
* the characters "-", "_" and "^" all need to be equivalent
|
||||
* (because they are treated so by different development environments).
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*
|
||||
* This array is designed for mapping upper and lower case letter
|
||||
* together for a case independent comparison. The mappings are
|
||||
* based upon ascii character sequences.
|
||||
*/
|
||||
static unsigned char charmap[] = {
|
||||
NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a',
|
||||
'\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
||||
|
||||
' ', '!', '"', '#', '$', '%', '&', '\'',
|
||||
'(', ')', '*', '+', ',', '-', '.', '/',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', ':', ';', '<', '=', '>', '?',
|
||||
|
||||
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '[', '\\', ']', '^', '_',
|
||||
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
|
||||
'x', 'y', 'z', '{', '|', '}', '~', 0x7f,
|
||||
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
|
||||
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
|
||||
0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
|
||||
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
|
||||
0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
|
||||
|
||||
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
|
||||
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
|
||||
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
|
||||
0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
|
||||
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
|
||||
0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
|
||||
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
|
||||
0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
|
||||
};
|
||||
|
||||
|
||||
/*=export_func strneqvcmp
|
||||
*
|
||||
* what: compare two strings with an equivalence mapping
|
||||
*
|
||||
* arg: + char const* + str1 + first string +
|
||||
* arg: + char const* + str2 + second string +
|
||||
* arg: + int + ct + compare length +
|
||||
*
|
||||
* ret_type: int
|
||||
* ret_desc: the difference between two differing characters
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* Using a character mapping, two strings are compared for "equivalence".
|
||||
* Each input character is mapped to a comparison character and the
|
||||
* mapped-to characters are compared for the two NUL terminated input strings.
|
||||
* The comparison is limited to @code{ct} bytes.
|
||||
* This function name is mapped to option_strneqvcmp so as to not conflict
|
||||
* with the POSIX name space.
|
||||
*
|
||||
* err: none checked. Caller responsible for seg faults.
|
||||
=*/
|
||||
int
|
||||
strneqvcmp(tCC* s1, tCC* s2, int ct)
|
||||
{
|
||||
for (; ct > 0; --ct) {
|
||||
unsigned char u1 = (unsigned char) *s1++;
|
||||
unsigned char u2 = (unsigned char) *s2++;
|
||||
int dif = charmap[ u1 ] - charmap[ u2 ];
|
||||
|
||||
if (dif != 0)
|
||||
return dif;
|
||||
|
||||
if (u1 == NUL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*=export_func streqvcmp
|
||||
*
|
||||
* what: compare two strings with an equivalence mapping
|
||||
*
|
||||
* arg: + char const* + str1 + first string +
|
||||
* arg: + char const* + str2 + second string +
|
||||
*
|
||||
* ret_type: int
|
||||
* ret_desc: the difference between two differing characters
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* Using a character mapping, two strings are compared for "equivalence".
|
||||
* Each input character is mapped to a comparison character and the
|
||||
* mapped-to characters are compared for the two NUL terminated input strings.
|
||||
* This function name is mapped to option_streqvcmp so as to not conflict
|
||||
* with the POSIX name space.
|
||||
*
|
||||
* err: none checked. Caller responsible for seg faults.
|
||||
=*/
|
||||
int
|
||||
streqvcmp(tCC* s1, tCC* s2)
|
||||
{
|
||||
for (;;) {
|
||||
unsigned char u1 = (unsigned char) *s1++;
|
||||
unsigned char u2 = (unsigned char) *s2++;
|
||||
int dif = charmap[ u1 ] - charmap[ u2 ];
|
||||
|
||||
if (dif != 0)
|
||||
return dif;
|
||||
|
||||
if (u1 == NUL)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func streqvmap
|
||||
*
|
||||
* what: Set the character mappings for the streqv functions
|
||||
*
|
||||
* arg: + char + From + Input character +
|
||||
* arg: + char + To + Mapped-to character +
|
||||
* arg: + int + ct + compare length +
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* Set the character mapping. If the count (@code{ct}) is set to zero, then
|
||||
* the map is cleared by setting all entries in the map to their index
|
||||
* value. Otherwise, the "@code{From}" character is mapped to the "@code{To}"
|
||||
* character. If @code{ct} is greater than 1, then @code{From} and @code{To}
|
||||
* are incremented and the process repeated until @code{ct} entries have been
|
||||
* set. For example,
|
||||
* @example
|
||||
* streqvmap('a', 'A', 26);
|
||||
* @end example
|
||||
* @noindent
|
||||
* will alter the mapping so that all English lower case letters
|
||||
* will map to upper case.
|
||||
*
|
||||
* This function name is mapped to option_streqvmap so as to not conflict
|
||||
* with the POSIX name space.
|
||||
*
|
||||
* err: none.
|
||||
=*/
|
||||
void
|
||||
streqvmap(char From, char To, int ct)
|
||||
{
|
||||
if (ct == 0) {
|
||||
ct = sizeof(charmap) - 1;
|
||||
do {
|
||||
charmap[ct] = (unsigned char)ct;
|
||||
} while (--ct >= 0);
|
||||
}
|
||||
|
||||
else {
|
||||
unsigned int chTo = (int)To & 0xFF;
|
||||
unsigned int chFrom = (int)From & 0xFF;
|
||||
|
||||
do {
|
||||
charmap[chFrom] = (unsigned char)chTo;
|
||||
chFrom++;
|
||||
chTo++;
|
||||
if ((chFrom >= sizeof(charmap)) || (chTo >= sizeof(charmap)))
|
||||
break;
|
||||
} while (--ct > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func strequate
|
||||
*
|
||||
* what: map a list of characters to the same value
|
||||
*
|
||||
* arg: + char const* + ch_list + characters to equivalence +
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* Each character in the input string get mapped to the first character
|
||||
* in the string.
|
||||
* This function name is mapped to option_strequate so as to not conflict
|
||||
* with the POSIX name space.
|
||||
*
|
||||
* err: none.
|
||||
=*/
|
||||
void
|
||||
strequate(char const* s)
|
||||
{
|
||||
if ((s != NULL) && (*s != NUL)) {
|
||||
unsigned char equiv = (unsigned)*s;
|
||||
while (*s != NUL)
|
||||
charmap[ (unsigned)*(s++) ] = equiv;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*=export_func strtransform
|
||||
*
|
||||
* what: convert a string into its mapped-to value
|
||||
*
|
||||
* arg: + char* + dest + output string +
|
||||
* arg: + char const* + src + input string +
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* Each character in the input string is mapped and the mapped-to
|
||||
* character is put into the output.
|
||||
* This function name is mapped to option_strtransform so as to not conflict
|
||||
* with the POSIX name space.
|
||||
*
|
||||
* The source and destination may be the same.
|
||||
*
|
||||
* err: none.
|
||||
=*/
|
||||
void
|
||||
strtransform(char* d, char const* s)
|
||||
{
|
||||
do {
|
||||
*(d++) = (char)charmap[ (unsigned)*s ];
|
||||
} while (*(s++) != NUL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/streqvcmp.c */
|
||||
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* @file text_mmap.c
|
||||
*
|
||||
* Map a text file, ensuring the text always has an ending NUL byte.
|
||||
*
|
||||
* Time-stamp: "2012-01-29 09:40:21 bkorb"
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
#if defined(HAVE_MMAP)
|
||||
# ifndef MAP_ANONYMOUS
|
||||
# ifdef MAP_ANON
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if ! defined(MAP_ANONYMOUS) && ! defined(HAVE_DEV_ZERO)
|
||||
/*
|
||||
* We must have either /dev/zero or anonymous mapping for
|
||||
* this to work.
|
||||
*/
|
||||
# undef HAVE_MMAP
|
||||
|
||||
# else
|
||||
# ifdef _SC_PAGESIZE
|
||||
# define GETPAGESIZE() sysconf(_SC_PAGESIZE)
|
||||
# else
|
||||
# define GETPAGESIZE() getpagesize()
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some weird systems require that a specifically invalid FD number
|
||||
* get passed in as an argument value. Which value is that? Well,
|
||||
* as everybody knows, if open(2) fails, it returns -1, so that must
|
||||
* be the value. :)
|
||||
*/
|
||||
#define AO_INVALID_FD -1
|
||||
|
||||
#define FILE_WRITABLE(_prt,_flg) \
|
||||
( (_prt & PROT_WRITE) \
|
||||
&& ((_flg & (MAP_SHARED|MAP_PRIVATE)) == MAP_SHARED))
|
||||
#define MAP_FAILED_PTR ((void*)MAP_FAILED)
|
||||
|
||||
/**
|
||||
* Load the contents of a text file. There are two separate implementations,
|
||||
* depending up on whether mmap(3) is available.
|
||||
*
|
||||
* If not available, malloc the file length plus one byte. Read it in
|
||||
* and NUL terminate.
|
||||
*
|
||||
* If available, first check to see if the text file size is a multiple of a
|
||||
* page size. If it is, map the file size plus an extra page from either
|
||||
* anonymous memory or from /dev/zero. Then map the file text on top of the
|
||||
* first pages of the anonymous/zero pages. Otherwise, just map the file
|
||||
* because there will be NUL bytes provided at the end.
|
||||
*
|
||||
* @param mapinfo a structure holding everything we need to know
|
||||
* about the mapping.
|
||||
*
|
||||
* @param pzFile name of the file, for error reporting.
|
||||
*/
|
||||
static void
|
||||
load_text_file(tmap_info_t * mapinfo, char const * pzFile)
|
||||
{
|
||||
#if ! defined(HAVE_MMAP)
|
||||
mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text");
|
||||
if (mapinfo->txt_data == NULL) {
|
||||
mapinfo->txt_errno = ENOMEM;
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
size_t sz = mapinfo->txt_size;
|
||||
char* pz = mapinfo->txt_data;
|
||||
|
||||
while (sz > 0) {
|
||||
ssize_t rdct = read(mapinfo->txt_fd, pz, sz);
|
||||
if (rdct <= 0) {
|
||||
mapinfo->txt_errno = errno;
|
||||
fprintf(stderr, zFSErrReadFile,
|
||||
errno, strerror(errno), pzFile);
|
||||
free(mapinfo->txt_data);
|
||||
return;
|
||||
}
|
||||
|
||||
pz += rdct;
|
||||
sz -= rdct;
|
||||
}
|
||||
|
||||
*pz = NUL;
|
||||
}
|
||||
|
||||
mapinfo->txt_errno = 0;
|
||||
|
||||
#else /* HAVE mmap */
|
||||
size_t const pgsz = GETPAGESIZE();
|
||||
void * map_addr = NULL;
|
||||
|
||||
(void)pzFile;
|
||||
|
||||
mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1);
|
||||
if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) {
|
||||
/*
|
||||
* The text is a multiple of a page boundary. We must map an
|
||||
* extra page so the text ends with a NUL.
|
||||
*/
|
||||
#if defined(MAP_ANONYMOUS)
|
||||
map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE,
|
||||
MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0);
|
||||
#else
|
||||
mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY);
|
||||
|
||||
if (mapinfo->txt_zero_fd == AO_INVALID_FD) {
|
||||
mapinfo->txt_errno = errno;
|
||||
return;
|
||||
}
|
||||
map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE, mapinfo->txt_zero_fd, 0);
|
||||
#endif
|
||||
if (map_addr == MAP_FAILED_PTR) {
|
||||
mapinfo->txt_errno = errno;
|
||||
return;
|
||||
}
|
||||
mapinfo->txt_flags |= MAP_FIXED;
|
||||
}
|
||||
|
||||
mapinfo->txt_data =
|
||||
mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot,
|
||||
mapinfo->txt_flags, mapinfo->txt_fd, 0);
|
||||
|
||||
if (mapinfo->txt_data == MAP_FAILED_PTR)
|
||||
mapinfo->txt_errno = errno;
|
||||
#endif /* HAVE_MMAP */
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure all the parameters are correct: we have a file name that
|
||||
* is a text file that we can read.
|
||||
*
|
||||
* @param fname the text file to map
|
||||
* @param prot the memory protections requested (read/write/etc.)
|
||||
* @param flags mmap flags
|
||||
* @param mapinfo a structure holding everything we need to know
|
||||
* about the mapping.
|
||||
*/
|
||||
static void
|
||||
validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo)
|
||||
{
|
||||
memset(mapinfo, 0, sizeof(*mapinfo));
|
||||
#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS)
|
||||
mapinfo->txt_zero_fd = AO_INVALID_FD;
|
||||
#endif
|
||||
mapinfo->txt_fd = AO_INVALID_FD;
|
||||
mapinfo->txt_prot = prot;
|
||||
mapinfo->txt_flags = flags;
|
||||
|
||||
/*
|
||||
* Make sure we can stat the regular file. Save the file size.
|
||||
*/
|
||||
{
|
||||
struct stat sb;
|
||||
if (stat(fname, &sb) != 0) {
|
||||
mapinfo->txt_errno = errno;
|
||||
return;
|
||||
}
|
||||
|
||||
if (! S_ISREG(sb.st_mode)) {
|
||||
mapinfo->txt_errno = errno = EINVAL;
|
||||
return;
|
||||
}
|
||||
|
||||
mapinfo->txt_size = sb.st_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map mmap flags and protections into open flags and do the open.
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* See if we will be updating the file. If we can alter the memory
|
||||
* and if we share the data and we are *not* copy-on-writing the data,
|
||||
* then our updates will show in the file, so we must open with
|
||||
* write access.
|
||||
*/
|
||||
int o_flag = FILE_WRITABLE(prot, flags) ? O_RDWR : O_RDONLY;
|
||||
|
||||
/*
|
||||
* If you're not sharing the file and you are writing to it,
|
||||
* then don't let anyone else have access to the file.
|
||||
*/
|
||||
if (((flags & MAP_SHARED) == 0) && (prot & PROT_WRITE))
|
||||
o_flag |= O_EXCL;
|
||||
|
||||
mapinfo->txt_fd = open(fname, o_flag);
|
||||
}
|
||||
|
||||
if (mapinfo->txt_fd == AO_INVALID_FD)
|
||||
mapinfo->txt_errno = errno;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close any files opened by the mapping.
|
||||
*
|
||||
* @param mi a structure holding everything we need to know about the map.
|
||||
*/
|
||||
static void
|
||||
close_mmap_files(tmap_info_t * mi)
|
||||
{
|
||||
if (mi->txt_fd == AO_INVALID_FD)
|
||||
return;
|
||||
|
||||
close(mi->txt_fd);
|
||||
mi->txt_fd = AO_INVALID_FD;
|
||||
|
||||
#if ! defined(MAP_ANONYMOUS)
|
||||
if (mi->txt_zero_fd == AO_INVALID_FD)
|
||||
return;
|
||||
|
||||
close(mi->txt_zero_fd);
|
||||
mi->txt_zero_fd = AO_INVALID_FD;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*=export_func text_mmap
|
||||
* private:
|
||||
*
|
||||
* what: map a text file with terminating NUL
|
||||
*
|
||||
* arg: char const*, pzFile, name of the file to map
|
||||
* arg: int, prot, mmap protections (see mmap(2))
|
||||
* arg: int, flags, mmap flags (see mmap(2))
|
||||
* arg: tmap_info_t*, mapinfo, returned info about the mapping
|
||||
*
|
||||
* ret-type: void*
|
||||
* ret-desc: The mmaped data address
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This routine will mmap a file into memory ensuring that there is at least
|
||||
* one @file{NUL} character following the file data. It will return the
|
||||
* address where the file contents have been mapped into memory. If there is a
|
||||
* problem, then it will return @code{MAP_FAILED} and set @code{errno}
|
||||
* appropriately.
|
||||
*
|
||||
* The named file does not exist, @code{stat(2)} will set @code{errno} as it
|
||||
* will. If the file is not a regular file, @code{errno} will be
|
||||
* @code{EINVAL}. At that point, @code{open(2)} is attempted with the access
|
||||
* bits set appropriately for the requested @code{mmap(2)} protections and flag
|
||||
* bits. On failure, @code{errno} will be set according to the documentation
|
||||
* for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as
|
||||
* that routine sets it. If @code{text_mmap} works to this point, a valid
|
||||
* address will be returned, but there may still be ``issues''.
|
||||
*
|
||||
* If the file size is not an even multiple of the system page size, then
|
||||
* @code{text_map} will return at this point and @code{errno} will be zero.
|
||||
* Otherwise, an anonymous map is attempted. If not available, then an attempt
|
||||
* is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the
|
||||
* address of the file's data is returned, bug @code{no} @file{NUL} characters
|
||||
* are mapped after the end of the data.
|
||||
*
|
||||
* see: mmap(2), open(2), stat(2)
|
||||
*
|
||||
* err: Any error code issued by mmap(2), open(2), stat(2) is possible.
|
||||
* Additionally, if the specified file is not a regular file, then
|
||||
* errno will be set to @code{EINVAL}.
|
||||
*
|
||||
* example:
|
||||
* #include <mylib.h>
|
||||
* tmap_info_t mi;
|
||||
* int no_nul;
|
||||
* void* data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi);
|
||||
* if (data == MAP_FAILED) return;
|
||||
* no_nul = (mi.txt_size == mi.txt_full_size);
|
||||
* << use the data >>
|
||||
* text_munmap(&mi);
|
||||
=*/
|
||||
void *
|
||||
text_mmap(char const * pzFile, int prot, int flags, tmap_info_t * mi)
|
||||
{
|
||||
validate_mmap(pzFile, prot, flags, mi);
|
||||
if (mi->txt_errno != 0)
|
||||
return MAP_FAILED_PTR;
|
||||
|
||||
load_text_file(mi, pzFile);
|
||||
|
||||
if (mi->txt_errno == 0)
|
||||
return mi->txt_data;
|
||||
|
||||
close_mmap_files(mi);
|
||||
|
||||
errno = mi->txt_errno;
|
||||
mi->txt_data = MAP_FAILED_PTR;
|
||||
return mi->txt_data;
|
||||
}
|
||||
|
||||
|
||||
/*=export_func text_munmap
|
||||
* private:
|
||||
*
|
||||
* what: unmap the data mapped in by text_mmap
|
||||
*
|
||||
* arg: tmap_info_t*, mapinfo, info about the mapping
|
||||
*
|
||||
* ret-type: int
|
||||
* ret-desc: -1 or 0. @code{errno} will have the error code.
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This routine will unmap the data mapped in with @code{text_mmap} and close
|
||||
* the associated file descriptors opened by that function.
|
||||
*
|
||||
* see: munmap(2), close(2)
|
||||
*
|
||||
* err: Any error code issued by munmap(2) or close(2) is possible.
|
||||
=*/
|
||||
int
|
||||
text_munmap(tmap_info_t * mi)
|
||||
{
|
||||
errno = 0;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
(void)munmap(mi->txt_data, mi->txt_full_size);
|
||||
|
||||
#else /* don't HAVE_MMAP */
|
||||
/*
|
||||
* IF the memory is writable *AND* it is not private (copy-on-write)
|
||||
* *AND* the memory is "sharable" (seen by other processes)
|
||||
* THEN rewrite the data. Emulate mmap visibility.
|
||||
*/
|
||||
if ( FILE_WRITABLE(mi->txt_prot, mi->txt_flags)
|
||||
&& (lseek(mi->txt_fd, 0, SEEK_SET) >= 0) ) {
|
||||
write(mi->txt_fd, mi->txt_data, mi->txt_size);
|
||||
}
|
||||
|
||||
free(mi->txt_data);
|
||||
#endif /* HAVE_MMAP */
|
||||
|
||||
mi->txt_errno = errno;
|
||||
close_mmap_files(mi);
|
||||
|
||||
return mi->txt_errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/text_mmap.c */
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
|
||||
/**
|
||||
* \file time.c
|
||||
*
|
||||
* Time-stamp: "2012-01-29 12:52:31 bkorb"
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*=export_func optionTimeVal
|
||||
* private:
|
||||
*
|
||||
* what: process an option with a time duration.
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Decipher a time duration value.
|
||||
=*/
|
||||
void
|
||||
optionTimeVal(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
time_t val;
|
||||
|
||||
if ((pOD->fOptState & OPTST_RESET) != 0)
|
||||
return;
|
||||
|
||||
val = parse_duration(pOD->optArg.argString);
|
||||
if (val == BAD_TIME) {
|
||||
fprintf(stderr, zNotDuration, pOpts->pzProgName, pOD->optArg.argString);
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
|
||||
(*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
pOD->optArg.argInt = (unsigned long)val;
|
||||
}
|
||||
|
||||
/*=export_func optionTimeDate
|
||||
* private:
|
||||
*
|
||||
* what: process an option with a time and date.
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* Decipher a time and date value.
|
||||
=*/
|
||||
void
|
||||
optionTimeDate(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
#if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV)
|
||||
if ((! HAS_pzPkgDataDir(pOpts)) || (pOpts->pzPkgDataDir == NULL))
|
||||
goto default_action;
|
||||
|
||||
/*
|
||||
* Export the DATEMSK environment variable. getdate_r() uses it to
|
||||
* find the file with the strptime formats. If we cannot find the file
|
||||
* we need ($PKGDATADIR/datemsk), then fall back to just a time duration.
|
||||
*/
|
||||
{
|
||||
static char * envptr = NULL;
|
||||
|
||||
if (envptr == NULL) {
|
||||
static char const fmt[] = "DATEMSK=%s/datemsk";
|
||||
envptr = AGALOC(sizeof(fmt) + strlen(pOpts->pzPkgDataDir), fmt);
|
||||
sprintf(envptr, fmt, pOpts->pzPkgDataDir);
|
||||
|
||||
putenv(envptr);
|
||||
}
|
||||
|
||||
if (access(envptr+8, R_OK) != 0)
|
||||
goto default_action;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the date to a time since the epoch and stash it in a long int.
|
||||
*/
|
||||
{
|
||||
struct tm stm;
|
||||
time_t tm;
|
||||
|
||||
if (getdate_r(pOD->optArg.argString, &stm) != 0) {
|
||||
fprintf(stderr, zNotDate, pOpts->pzProgName,
|
||||
pOD->optArg.argString);
|
||||
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
|
||||
(*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
tm = mktime(&stm);
|
||||
|
||||
if (pOD->fOptState & OPTST_ALLOC_ARG) {
|
||||
AGFREE(pOD->optArg.argString);
|
||||
pOD->fOptState &= ~OPTST_ALLOC_ARG;
|
||||
}
|
||||
|
||||
pOD->optArg.argInt = tm;
|
||||
}
|
||||
return;
|
||||
|
||||
default_action:
|
||||
|
||||
#endif
|
||||
optionTimeVal(pOpts, pOD);
|
||||
if (pOD->optArg.argInt != BAD_TIME)
|
||||
pOD->optArg.argInt += (unsigned long)time(NULL);
|
||||
}
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/time.c */
|
||||
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* This file defines the string_tokenize interface
|
||||
* Time-stamp: "2012-03-04 13:23:50 bkorb"
|
||||
*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define cc_t const unsigned char
|
||||
#define ch_t unsigned char
|
||||
|
||||
/* = = = START-STATIC-FORWARD = = = */
|
||||
static void
|
||||
copy_cooked(ch_t** ppDest, char const ** ppSrc);
|
||||
|
||||
static void
|
||||
copy_raw(ch_t** ppDest, char const ** ppSrc);
|
||||
|
||||
static token_list_t *
|
||||
alloc_token_list(char const * str);
|
||||
/* = = = END-STATIC-FORWARD = = = */
|
||||
|
||||
static void
|
||||
copy_cooked(ch_t** ppDest, char const ** ppSrc)
|
||||
{
|
||||
ch_t* pDest = (ch_t*)*ppDest;
|
||||
const ch_t* pSrc = (const ch_t*)(*ppSrc + 1);
|
||||
|
||||
for (;;) {
|
||||
ch_t ch = *(pSrc++);
|
||||
switch (ch) {
|
||||
case NUL: *ppSrc = NULL; return;
|
||||
case '"': goto done;
|
||||
case '\\':
|
||||
pSrc += ao_string_cook_escape_char((char*)pSrc, (char*)&ch, 0x7F);
|
||||
if (ch == 0x7F)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
*(pDest++) = ch;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
*ppDest = (ch_t*)pDest; /* next spot for storing character */
|
||||
*ppSrc = (char const *)pSrc; /* char following closing quote */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
copy_raw(ch_t** ppDest, char const ** ppSrc)
|
||||
{
|
||||
ch_t* pDest = *ppDest;
|
||||
cc_t* pSrc = (cc_t*) (*ppSrc + 1);
|
||||
|
||||
for (;;) {
|
||||
ch_t ch = *(pSrc++);
|
||||
switch (ch) {
|
||||
case NUL: *ppSrc = NULL; return;
|
||||
case '\'': goto done;
|
||||
case '\\':
|
||||
/*
|
||||
* *Four* escapes are handled: newline removal, escape char
|
||||
* quoting and apostrophe quoting
|
||||
*/
|
||||
switch (*pSrc) {
|
||||
case NUL: *ppSrc = NULL; return;
|
||||
case '\r':
|
||||
if (*(++pSrc) == NL)
|
||||
++pSrc;
|
||||
continue;
|
||||
|
||||
case NL:
|
||||
++pSrc;
|
||||
continue;
|
||||
|
||||
case '\'':
|
||||
ch = '\'';
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case '\\':
|
||||
++pSrc;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
default:
|
||||
*(pDest++) = ch;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
*ppDest = pDest; /* next spot for storing character */
|
||||
*ppSrc = (char const *) pSrc; /* char following closing quote */
|
||||
}
|
||||
|
||||
static token_list_t *
|
||||
alloc_token_list(char const * str)
|
||||
{
|
||||
token_list_t * res;
|
||||
|
||||
int max_token_ct = 2; /* allow for trailing NULL pointer & NUL on string */
|
||||
|
||||
if (str == NULL) goto enoent_res;
|
||||
|
||||
/*
|
||||
* Trim leading white space. Use "ENOENT" and a NULL return to indicate
|
||||
* an empty string was passed.
|
||||
*/
|
||||
str = SPN_WHITESPACE_CHARS(str);
|
||||
if (*str == NUL) goto enoent_res;
|
||||
|
||||
/*
|
||||
* Take an approximate count of tokens. If no quoted strings are used,
|
||||
* it will be accurate. If quoted strings are used, it will be a little
|
||||
* high and we'll squander the space for a few extra pointers.
|
||||
*/
|
||||
{
|
||||
char const * pz = str;
|
||||
|
||||
do {
|
||||
max_token_ct++;
|
||||
pz = BRK_WHITESPACE_CHARS(pz+1);
|
||||
pz = SPN_WHITESPACE_CHARS(pz);
|
||||
} while (*pz != NUL);
|
||||
|
||||
res = malloc(sizeof(*res) + (pz - str)
|
||||
+ (max_token_ct * sizeof(ch_t*)));
|
||||
}
|
||||
|
||||
if (res == NULL)
|
||||
errno = ENOMEM;
|
||||
else res->tkn_list[0] = (ch_t*)(res->tkn_list + (max_token_ct - 1));
|
||||
|
||||
return res;
|
||||
|
||||
enoent_res:
|
||||
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*=export_func ao_string_tokenize
|
||||
*
|
||||
* what: tokenize an input string
|
||||
*
|
||||
* arg: + char const* + string + string to be tokenized +
|
||||
*
|
||||
* ret_type: token_list_t*
|
||||
* ret_desc: pointer to a structure that lists each token
|
||||
*
|
||||
* doc:
|
||||
*
|
||||
* This function will convert one input string into a list of strings.
|
||||
* The list of strings is derived by separating the input based on
|
||||
* white space separation. However, if the input contains either single
|
||||
* or double quote characters, then the text after that character up to
|
||||
* a matching quote will become the string in the list.
|
||||
*
|
||||
* The returned pointer should be deallocated with @code{free(3C)} when
|
||||
* are done using the data. The data are placed in a single block of
|
||||
* allocated memory. Do not deallocate individual token/strings.
|
||||
*
|
||||
* The structure pointed to will contain at least these two fields:
|
||||
* @table @samp
|
||||
* @item tkn_ct
|
||||
* The number of tokens found in the input string.
|
||||
* @item tok_list
|
||||
* An array of @code{tkn_ct + 1} pointers to substring tokens, with
|
||||
* the last pointer set to NULL.
|
||||
* @end table
|
||||
*
|
||||
* There are two types of quoted strings: single quoted (@code{'}) and
|
||||
* double quoted (@code{"}). Singly quoted strings are fairly raw in that
|
||||
* escape characters (@code{\\}) are simply another character, except when
|
||||
* preceding the following characters:
|
||||
* @example
|
||||
* @code{\\} double backslashes reduce to one
|
||||
* @code{'} incorporates the single quote into the string
|
||||
* @code{\n} suppresses both the backslash and newline character
|
||||
* @end example
|
||||
*
|
||||
* Double quote strings are formed according to the rules of string
|
||||
* constants in ANSI-C programs.
|
||||
*
|
||||
* example:
|
||||
* @example
|
||||
* #include <stdlib.h>
|
||||
* int ix;
|
||||
* token_list_t* ptl = ao_string_tokenize(some_string)
|
||||
* for (ix = 0; ix < ptl->tkn_ct; ix++)
|
||||
* do_something_with_tkn(ptl->tkn_list[ix]);
|
||||
* free(ptl);
|
||||
* @end example
|
||||
* Note that everything is freed with the one call to @code{free(3C)}.
|
||||
*
|
||||
* err:
|
||||
* NULL is returned and @code{errno} will be set to indicate the problem:
|
||||
* @itemize @bullet
|
||||
* @item
|
||||
* @code{EINVAL} - There was an unterminated quoted string.
|
||||
* @item
|
||||
* @code{ENOENT} - The input string was empty.
|
||||
* @item
|
||||
* @code{ENOMEM} - There is not enough memory.
|
||||
* @end itemize
|
||||
=*/
|
||||
token_list_t*
|
||||
ao_string_tokenize(char const* str)
|
||||
{
|
||||
token_list_t* res = alloc_token_list(str);
|
||||
ch_t* pzDest;
|
||||
|
||||
/*
|
||||
* Now copy each token into the output buffer.
|
||||
*/
|
||||
if (res == NULL)
|
||||
return res;
|
||||
|
||||
pzDest = (ch_t*)(res->tkn_list[0]);
|
||||
res->tkn_ct = 0;
|
||||
|
||||
do {
|
||||
res->tkn_list[ res->tkn_ct++ ] = pzDest;
|
||||
for (;;) {
|
||||
int ch = (ch_t)*str;
|
||||
if (IS_WHITESPACE_CHAR(ch)) {
|
||||
found_white_space:
|
||||
str = SPN_WHITESPACE_CHARS(str+1);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case '"':
|
||||
copy_cooked(&pzDest, &str);
|
||||
if (str == NULL) {
|
||||
free(res);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if (IS_WHITESPACE_CHAR(*str))
|
||||
goto found_white_space;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
copy_raw(&pzDest, &str);
|
||||
if (str == NULL) {
|
||||
free(res);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
if (IS_WHITESPACE_CHAR(*str))
|
||||
goto found_white_space;
|
||||
break;
|
||||
|
||||
case NUL:
|
||||
goto copy_done;
|
||||
|
||||
default:
|
||||
str++;
|
||||
*(pzDest++) = (unsigned char)ch;
|
||||
}
|
||||
} copy_done:;
|
||||
|
||||
/*
|
||||
* NUL terminate the last token and see if we have any more tokens.
|
||||
*/
|
||||
*(pzDest++) = NUL;
|
||||
} while (*str != NUL);
|
||||
|
||||
res->tkn_list[ res->tkn_ct ] = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if (argc == 1) {
|
||||
printf("USAGE: %s arg [ ... ]\n", *argv);
|
||||
return 1;
|
||||
}
|
||||
while (--argc > 0) {
|
||||
char* arg = *(++argv);
|
||||
token_list_t* p = ao_string_tokenize(arg);
|
||||
if (p == NULL) {
|
||||
printf("Parsing string ``%s'' failed:\n\terrno %d (%s)\n",
|
||||
arg, errno, strerror(errno));
|
||||
} else {
|
||||
int ix = 0;
|
||||
printf("Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct);
|
||||
do {
|
||||
printf(" %3d: ``%s''\n", ix+1, p->tkn_list[ix]);
|
||||
} while (++ix < p->tkn_ct);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/tokenize.c */
|
||||
+1053
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,123 @@
|
||||
/* ANSI-C code produced by gperf version 3.0.4 */
|
||||
|
||||
|
||||
#if 0 /* gperf build options: */
|
||||
// %struct-type
|
||||
// %language=ANSI-C
|
||||
// %includes
|
||||
// %global-table
|
||||
// %omit-struct-type
|
||||
// %readonly-tables
|
||||
// %compare-strncmp
|
||||
//
|
||||
// %define slot-name vtp_name
|
||||
// %define hash-function-name value_type_hash
|
||||
// %define lookup-function-name find_value_type_name
|
||||
// %define word-array-name value_type_table
|
||||
// %define initializer-suffix ,VTP_COUNT_KWD
|
||||
#endif /* gperf build options: */
|
||||
|
||||
#include "value-type.h"
|
||||
|
||||
typedef struct {
|
||||
char const * vtp_name;
|
||||
value_type_enum_t vtp_id;
|
||||
} value_type_map_t;
|
||||
#include <string.h>
|
||||
|
||||
/* maximum key range = 20, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#endif
|
||||
#endif
|
||||
inline static unsigned int
|
||||
value_type_hash (register const char *str, register unsigned int len)
|
||||
{
|
||||
static const unsigned char asso_values[] =
|
||||
{
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 10, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 5, 23, 23, 5, 0, 0, 23, 15, 23,
|
||||
23, 10, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23
|
||||
};
|
||||
return len + asso_values[(unsigned char)str[2]];
|
||||
}
|
||||
|
||||
static const value_type_map_t value_type_table[] =
|
||||
{
|
||||
{"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
|
||||
{"",VTP_COUNT_KWD},
|
||||
{"set", VTP_KWD_SET},
|
||||
{"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
|
||||
{"nested", VTP_KWD_NESTED},
|
||||
{"integer", VTP_KWD_INTEGER},
|
||||
{"",VTP_COUNT_KWD},
|
||||
{"bool", VTP_KWD_BOOL},
|
||||
{"",VTP_COUNT_KWD},
|
||||
{"string", VTP_KWD_STRING},
|
||||
{"boolean", VTP_KWD_BOOLEAN},
|
||||
{"",VTP_COUNT_KWD},
|
||||
{"set-membership", VTP_KWD_SET_MEMBERSHIP},
|
||||
{"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
|
||||
{"keyword", VTP_KWD_KEYWORD},
|
||||
{"",VTP_COUNT_KWD},
|
||||
{"hierarchy", VTP_KWD_HIERARCHY},
|
||||
{"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
|
||||
{"invalid", VTP_KWD_INVALID}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
|
||||
__attribute__ ((__gnu_inline__))
|
||||
#endif
|
||||
#endif
|
||||
static inline const value_type_map_t *
|
||||
find_value_type_name (register const char *str, register unsigned int len)
|
||||
{
|
||||
if (len <= 14 && len >= 3)
|
||||
{
|
||||
register int key = value_type_hash (str, len);
|
||||
|
||||
if (key <= 22 && key >= 0)
|
||||
{
|
||||
register const char *s = value_type_table[key].vtp_name;
|
||||
|
||||
if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
|
||||
return &value_type_table[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
value_type_enum_t
|
||||
find_value_type_id(char const * str, unsigned int len)
|
||||
{
|
||||
const value_type_map_t * p =
|
||||
find_value_type_name(str, len);
|
||||
return (p == 0) ? VTP_KWD_INVALID : p->vtp_id;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Generated header for gperf generated source Sun May 6 16:20:59 PDT 2012
|
||||
* This file enumerates the list of names and declares the
|
||||
* procedure for mapping string names to the enum value.
|
||||
*/
|
||||
#ifndef AUTOOPTS_VALUE_TYPE_H_GUARD
|
||||
#define AUTOOPTS_VALUE_TYPE_H_GUARD 1
|
||||
|
||||
typedef enum {
|
||||
VTP_KWD_INVALID,
|
||||
VTP_KWD_STRING,
|
||||
VTP_KWD_INTEGER,
|
||||
VTP_KWD_BOOLEAN,
|
||||
VTP_KWD_BOOL,
|
||||
VTP_KWD_KEYWORD,
|
||||
VTP_KWD_SET,
|
||||
VTP_KWD_SET_MEMBERSHIP,
|
||||
VTP_KWD_NESTED,
|
||||
VTP_KWD_HIERARCHY,
|
||||
VTP_COUNT_KWD
|
||||
} value_type_enum_t;
|
||||
|
||||
extern value_type_enum_t
|
||||
find_value_type_id(char const * str, unsigned int len);
|
||||
#endif /* AUTOOPTS_VALUE_TYPE_H_GUARD */
|
||||
@@ -0,0 +1,211 @@
|
||||
|
||||
/*
|
||||
* Time-stamp: "2012-01-29 19:44:24 bkorb"
|
||||
*
|
||||
* This module implements the default usage procedure for
|
||||
* Automated Options. It may be overridden, of course.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of AutoOpts, a companion to AutoGen.
|
||||
* AutoOpts is free software.
|
||||
* AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
|
||||
*
|
||||
* AutoOpts is available under any one of two licenses. The license
|
||||
* in use must be one of these two and the choice is under the control
|
||||
* of the user of the license.
|
||||
*
|
||||
* The GNU Lesser General Public License, version 3 or later
|
||||
* See the files "COPYING.lgplv3" and "COPYING.gplv3"
|
||||
*
|
||||
* The Modified Berkeley Software Distribution License
|
||||
* See the file "COPYING.mbsd"
|
||||
*
|
||||
* These files have the following md5sums:
|
||||
*
|
||||
* 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
|
||||
* 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
|
||||
* 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
|
||||
*/
|
||||
|
||||
/*=export_func optionVersion
|
||||
*
|
||||
* what: return the compiled AutoOpts version number
|
||||
* ret_type: char const*
|
||||
* ret_desc: the version string in constant memory
|
||||
* doc:
|
||||
* Returns the full version string compiled into the library.
|
||||
* The returned string cannot be modified.
|
||||
=*/
|
||||
char const*
|
||||
optionVersion(void)
|
||||
{
|
||||
static char const zVersion[] =
|
||||
STR(AO_CURRENT.AO_REVISION);
|
||||
|
||||
return zVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select among various ways to emit version information.
|
||||
*
|
||||
* @param pOpts the option descriptor
|
||||
* @param fp the output stream
|
||||
*/
|
||||
static void
|
||||
emit_simple_ver(tOptions * pOpts, FILE * fp)
|
||||
{
|
||||
/*
|
||||
* Use the supplied string
|
||||
*/
|
||||
if (pOpts->pzFullVersion != NULL)
|
||||
fputs(pOpts->pzFullVersion, fp);
|
||||
|
||||
/*
|
||||
* Extract the interesting part of the copyright string
|
||||
*/
|
||||
else if (pOpts->pzCopyright != NULL) {
|
||||
char const * pe = strchr(pOpts->pzCopyright, NL);
|
||||
if (pe == NULL)
|
||||
pe = pOpts->pzCopyright + strlen(pOpts->pzCopyright);
|
||||
fwrite(pOpts->pzCopyright, 1, pe - pOpts->pzCopyright, fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the interesting part of the usage title string
|
||||
*/
|
||||
else {
|
||||
char const * pe = strchr(pOpts->pzUsageTitle, NL);
|
||||
if (pe == NULL)
|
||||
pe = pOpts->pzUsageTitle + strlen(pOpts->pzUsageTitle);
|
||||
fwrite(pOpts->pzUsageTitle, 1, pe - pOpts->pzUsageTitle, fp);
|
||||
}
|
||||
fputc(NL, fp);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_copy_ver(tOptions * pOpts, FILE * fp)
|
||||
{
|
||||
if (pOpts->pzCopyright != NULL)
|
||||
fputs(pOpts->pzCopyright, fp);
|
||||
|
||||
else if (pOpts->pzFullVersion != NULL)
|
||||
fputs(pOpts->pzFullVersion, fp);
|
||||
|
||||
else {
|
||||
char const * pe = strchr(pOpts->pzUsageTitle, NL);
|
||||
if (pe == NULL)
|
||||
pe = pOpts->pzUsageTitle + strlen(pOpts->pzUsageTitle);
|
||||
fwrite(pOpts->pzUsageTitle, 1, pe - pOpts->pzCopyright, fp);
|
||||
}
|
||||
|
||||
fputc(NL, fp);
|
||||
|
||||
if (HAS_pzPkgDataDir(pOpts) && (pOpts->pzPackager != NULL))
|
||||
fputs(pOpts->pzPackager, fp);
|
||||
|
||||
else if (pOpts->pzBugAddr != NULL)
|
||||
fprintf(fp, zPlsSendBugs, pOpts->pzBugAddr);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_copy_note(tOptions * pOpts, FILE * fp)
|
||||
{
|
||||
if (pOpts->pzCopyright != NULL) {
|
||||
fputs(pOpts->pzCopyright, fp);
|
||||
fputc(NL, fp);
|
||||
}
|
||||
|
||||
if (pOpts->pzCopyNotice != NULL) {
|
||||
fputs(pOpts->pzCopyNotice, fp);
|
||||
fputc(NL, fp);
|
||||
}
|
||||
|
||||
fprintf(fp, zAO_Ver, optionVersion());
|
||||
|
||||
if (HAS_pzPkgDataDir(pOpts) && (pOpts->pzPackager != NULL))
|
||||
fputs(pOpts->pzPackager, fp);
|
||||
|
||||
else if (pOpts->pzBugAddr != NULL)
|
||||
fprintf(fp, zPlsSendBugs, pOpts->pzBugAddr);
|
||||
}
|
||||
|
||||
static void
|
||||
print_ver(tOptions * pOpts, tOptDesc * pOD, FILE * fp)
|
||||
{
|
||||
char ch;
|
||||
|
||||
/*
|
||||
* IF we have an argument for this option, use it
|
||||
* Otherwise, default to version only or copyright note,
|
||||
* depending on whether the layout is GNU standard form or not.
|
||||
*/
|
||||
if ( (pOD->fOptState & OPTST_ARG_OPTIONAL)
|
||||
&& (pOD->optArg.argString != NULL)
|
||||
&& (pOD->optArg.argString[0] != NUL))
|
||||
|
||||
ch = pOD->optArg.argString[0];
|
||||
|
||||
else {
|
||||
set_usage_flags(pOpts, NULL);
|
||||
ch = (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? 'c' : 'v';
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case NUL: /* arg provided, but empty */
|
||||
case 'v': case 'V': emit_simple_ver(pOpts, fp); break;
|
||||
case 'c': case 'C': emit_copy_ver(pOpts, fp); break;
|
||||
case 'n': case 'N': emit_copy_note(pOpts, fp); break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, zBadVerArg, ch);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fflush(fp);
|
||||
if (ferror(fp) != 0) {
|
||||
fputs(zOutputFail, stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/*=export_func optionPrintVersion
|
||||
* private:
|
||||
*
|
||||
* what: Print the program version
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* This routine will print the version to stdout.
|
||||
=*/
|
||||
void
|
||||
optionPrintVersion(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
print_ver(pOpts, pOD, stdout);
|
||||
}
|
||||
|
||||
/*=export_func optionVersionStderr
|
||||
* private:
|
||||
*
|
||||
* what: Print the program version to stderr
|
||||
* arg: + tOptions* + pOpts + program options descriptor +
|
||||
* arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
|
||||
*
|
||||
* doc:
|
||||
* This routine will print the version to stderr.
|
||||
=*/
|
||||
void
|
||||
optionVersionStderr(tOptions * pOpts, tOptDesc * pOD)
|
||||
{
|
||||
print_ver(pOpts, pOD, stderr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-file-style: "stroustrup"
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
* end of autoopts/version.c */
|
||||
@@ -0,0 +1,114 @@
|
||||
/* ANSI-C code produced by gperf version 3.0.4 */
|
||||
|
||||
|
||||
#if 0 /* gperf build options: */
|
||||
// %struct-type
|
||||
// %language=ANSI-C
|
||||
// %includes
|
||||
// %global-table
|
||||
// %omit-struct-type
|
||||
// %readonly-tables
|
||||
// %compare-strncmp
|
||||
//
|
||||
// %define slot-name xat_name
|
||||
// %define hash-function-name xat_attribute_hash
|
||||
// %define lookup-function-name find_xat_attribute_name
|
||||
// %define word-array-name xat_attribute_table
|
||||
// %define initializer-suffix ,XAT_COUNT_KWD
|
||||
#endif /* gperf build options: */
|
||||
|
||||
#include "xat-attribute.h"
|
||||
|
||||
typedef struct {
|
||||
char const * xat_name;
|
||||
xat_attribute_enum_t xat_id;
|
||||
} xat_attribute_map_t;
|
||||
#include <string.h>
|
||||
|
||||
/* maximum key range = 9, duplicates = 0 */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#endif
|
||||
#endif
|
||||
inline static unsigned int
|
||||
xat_attribute_hash (register const char *str, register unsigned int len)
|
||||
{
|
||||
static const unsigned char asso_values[] =
|
||||
{
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 0,
|
||||
13, 13, 13, 13, 13, 5, 13, 5, 13, 0,
|
||||
13, 13, 13, 13, 13, 13, 0, 0, 13, 0,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13
|
||||
};
|
||||
return len + asso_values[(unsigned char)str[0]];
|
||||
}
|
||||
|
||||
static const xat_attribute_map_t xat_attribute_table[] =
|
||||
{
|
||||
{"",XAT_COUNT_KWD}, {"",XAT_COUNT_KWD},
|
||||
{"",XAT_COUNT_KWD}, {"",XAT_COUNT_KWD},
|
||||
{"type", XAT_KWD_TYPE},
|
||||
{"words", XAT_KWD_WORDS},
|
||||
{"cooked", XAT_KWD_COOKED},
|
||||
{"members", XAT_KWD_MEMBERS},
|
||||
{"uncooked", XAT_KWD_UNCOOKED},
|
||||
{"keep", XAT_KWD_KEEP},
|
||||
{"",XAT_COUNT_KWD}, {"",XAT_COUNT_KWD},
|
||||
{"invalid", XAT_KWD_INVALID}
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
|
||||
__attribute__ ((__gnu_inline__))
|
||||
#endif
|
||||
#endif
|
||||
static inline const xat_attribute_map_t *
|
||||
find_xat_attribute_name (register const char *str, register unsigned int len)
|
||||
{
|
||||
if (len <= 8 && len >= 4)
|
||||
{
|
||||
register int key = xat_attribute_hash (str, len);
|
||||
|
||||
if (key <= 12 && key >= 0)
|
||||
{
|
||||
register const char *s = xat_attribute_table[key].xat_name;
|
||||
|
||||
if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
|
||||
return &xat_attribute_table[key];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
xat_attribute_enum_t
|
||||
find_xat_attribute_id(char const * str, unsigned int len)
|
||||
{
|
||||
const xat_attribute_map_t * p =
|
||||
find_xat_attribute_name(str, len);
|
||||
return (p == 0) ? XAT_KWD_INVALID : p->xat_id;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Generated header for gperf generated source Sun May 6 16:20:59 PDT 2012
|
||||
* This file enumerates the list of names and declares the
|
||||
* procedure for mapping string names to the enum value.
|
||||
*/
|
||||
#ifndef AUTOOPTS_XAT_ATTRIBUTE_H_GUARD
|
||||
#define AUTOOPTS_XAT_ATTRIBUTE_H_GUARD 1
|
||||
|
||||
typedef enum {
|
||||
XAT_KWD_INVALID,
|
||||
XAT_KWD_TYPE,
|
||||
XAT_KWD_WORDS,
|
||||
XAT_KWD_MEMBERS,
|
||||
XAT_KWD_COOKED,
|
||||
XAT_KWD_UNCOOKED,
|
||||
XAT_KWD_KEEP,
|
||||
XAT_COUNT_KWD
|
||||
} xat_attribute_enum_t;
|
||||
|
||||
extern xat_attribute_enum_t
|
||||
find_xat_attribute_id(char const * str, unsigned int len);
|
||||
#endif /* AUTOOPTS_XAT_ATTRIBUTE_H_GUARD */
|
||||
+14
-2
@@ -1,11 +1,23 @@
|
||||
AM_CPPFLAGS = -I$(srcdir)../gl/ -I$(builddir)../gl/ \
|
||||
-I$(srcdir)/ -I$(builddir)/../
|
||||
|
||||
EXTRA_DIST = ocserv.1
|
||||
|
||||
bin_PROGRAMS = ocserv
|
||||
|
||||
ocserv_SOURCES = main.c vpn.c http_auth.c tlslib.c cookies.c http-parser/http_parser.c \
|
||||
vpn.h auth.h cookies.h tlslib.h http-parser/http_parser.h log.c tun.c tun.h \
|
||||
uthash.h
|
||||
config.c
|
||||
|
||||
ocserv_LDADD = ../gl/libgnu.a
|
||||
ocserv_SOURCES += ocserv-args.def ocserv-args.c ocserv-args.h
|
||||
|
||||
ocserv_LDADD = ../gl/libgnu.a ../libopts/libopts.a
|
||||
ocserv_LDADD += $(LIBGNUTLS_LIBS) $(GDBM_LIBS)
|
||||
|
||||
ocserv-args.c ocserv-args.h: $(srcdir)/ocserv-args.def
|
||||
-autogen ocserv-args.def
|
||||
|
||||
ocserv.1: ocserv-args.def
|
||||
-sed 's/@subheading \(.*\)/@*\n@var{\1}\n@*/' $< > "$<".tmp && \
|
||||
autogen -DMAN_SECTION=1 -Tagman-cmd.tpl "$<".tmp && \
|
||||
rm -f "$<".tmp
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <ocserv-args.h>
|
||||
#include <vpn.h>
|
||||
|
||||
|
||||
int cmd_parser (int argc, char **argv, struct cfg_st* config)
|
||||
{
|
||||
const char* cfg_file;
|
||||
|
||||
memset(config, 0, sizeof(*config));
|
||||
|
||||
optionProcess( &ocservOptions, argc, argv);
|
||||
|
||||
if (HAVE_OPT(FOREGROUND))
|
||||
config->foreground = 1;
|
||||
|
||||
if (HAVE_OPT(CONFIG)) {
|
||||
cfg_file = OPT_ARG(CONFIG);
|
||||
} else {
|
||||
fprintf(stderr, "Please use the -c option to specify a configuration file, or --help for more information.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
+9
-4
@@ -74,7 +74,6 @@ static void tls_audit_log_func(gnutls_session_t session, const char *str)
|
||||
|
||||
static struct cfg_st config = {
|
||||
.auth_types = AUTH_TYPE_USERNAME_PASS,
|
||||
.workers = 1,
|
||||
.name = NULL,
|
||||
.port = 3333,
|
||||
.cert = "./test.pem",
|
||||
@@ -82,7 +81,8 @@ static struct cfg_st config = {
|
||||
.cert_req = GNUTLS_CERT_IGNORE,
|
||||
.cert_user_oid =
|
||||
GNUTLS_OID_LDAP_UID /* or just GNUTLS_OID_X520_COMMON_NAME */ ,
|
||||
.root_dir = "root/",
|
||||
#warning fix chroot
|
||||
.chroot_dir = "root/",
|
||||
.cookie_validity = 3600,
|
||||
.db_file = "/tmp/db",
|
||||
.uid = 65534,
|
||||
@@ -310,9 +310,8 @@ static void clear_proc_list(struct proc_list_st* clist)
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
int fd, pid, e;
|
||||
struct tls_st creds;
|
||||
struct listen_list_st llist;
|
||||
@@ -327,6 +326,7 @@ int main(void)
|
||||
struct timeval tv;
|
||||
int cmd_fd[2];
|
||||
struct worker_st ws;
|
||||
struct cfg_st config;
|
||||
|
||||
struct sockaddr_storage tmp_addr;
|
||||
socklen_t tmp_addr_len;
|
||||
@@ -341,6 +341,11 @@ int main(void)
|
||||
signal(SIGALRM, handle_alarm);
|
||||
|
||||
/* XXX load configuration */
|
||||
ret = cmd_parser(argc, argv, &config);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error in arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
#warning read configuration from file
|
||||
|
||||
/* Listen to network ports */
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ocserv-args.c)
|
||||
*
|
||||
* It has been AutoGen-ed January 30, 2013 at 01:39:04 AM by AutoGen 5.16
|
||||
* From the definitions ocserv-args.def
|
||||
* and the template file options
|
||||
*
|
||||
* Generated from AutoOpts 36:4:11 templates.
|
||||
*
|
||||
* AutoOpts is a copyrighted work. This source file is not encumbered
|
||||
* by AutoOpts licensing, but is provided under the licensing terms chosen
|
||||
* by the ocserv author or copyright holder. AutoOpts is
|
||||
* licensed under the terms of the LGPL. The redistributable library
|
||||
* (``libopts'') is licensed under the terms of either the LGPL or, at the
|
||||
* users discretion, the BSD license. See the AutoOpts and/or libopts sources
|
||||
* for details.
|
||||
*
|
||||
* The ocserv program is copyrighted and licensed
|
||||
* under the following terms:
|
||||
*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* GNU General Public License, version 2 <http://gnu.org/licenses/gpl.html>
|
||||
*
|
||||
* ocserv is free software: you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* ocserv is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License,
|
||||
* version 2, along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __doxygen__
|
||||
#define OPTION_CODE_COMPILE 1
|
||||
#include "ocserv-args.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern FILE * option_usage_fp;
|
||||
|
||||
/* TRANSLATORS: choose the translation for option names wisely because you
|
||||
cannot ever change your mind. */
|
||||
#define zCopyright (ocserv_opt_strs+0)
|
||||
#define zLicenseDescrip (ocserv_opt_strs+248)
|
||||
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ocserv option static const strings
|
||||
*/
|
||||
static char const ocserv_opt_strs[1208] =
|
||||
/* 0 */ "ocserv\n"
|
||||
"Copyright (C) 2013 Nikos Mavrogiannopoulos, all rights reserved.\n"
|
||||
"This is free software. It is licensed for use, modification and\n"
|
||||
"redistribution under the terms of the\n"
|
||||
"GNU General Public License, version 2 <http://gnu.org/licenses/gpl.html>\n\0"
|
||||
/* 248 */ "ocserv is free software: you can redistribute it and/or modify it under the\n"
|
||||
"terms of version 2 of the GNU General Public License, as published by the\n"
|
||||
"Free Software Foundation.\n\n"
|
||||
"ocserv is distributed in the hope that it will be useful, but WITHOUT ANY\n"
|
||||
"WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n"
|
||||
"FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\n"
|
||||
"details.\n\n"
|
||||
"You should have received a copy of the GNU General Public License, version\n"
|
||||
"2, along with this program. If not, see <http://www.gnu.org/licenses/>.\n\0"
|
||||
/* 803 */ "Do not fork into background.\0"
|
||||
/* 832 */ "FOREGROUND\0"
|
||||
/* 843 */ "foreground\0"
|
||||
/* 854 */ "Configuration file for the server.\0"
|
||||
/* 889 */ "CONFIG\0"
|
||||
/* 896 */ "config\0"
|
||||
/* 903 */ "Display extended usage information and exit\0"
|
||||
/* 947 */ "help\0"
|
||||
/* 952 */ "Extended usage information passed thru pager\0"
|
||||
/* 997 */ "more-help\0"
|
||||
/* 1007 */ "OCSERV\0"
|
||||
/* 1014 */ "ocserv - OpenConnect server\n"
|
||||
"USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
|
||||
/* 1100 */ "nmav@gnutls.org\0"
|
||||
/* 1116 */ "\n\n\0"
|
||||
/* 1119 */ "\n"
|
||||
"OpenConnect VPN server.\n\0"
|
||||
/* 1145 */ "Usage: ocserv [options]\n"
|
||||
"ocserv --help for usage instructions.\n";
|
||||
|
||||
/*
|
||||
* foreground option description:
|
||||
*/
|
||||
#define FOREGROUND_DESC (ocserv_opt_strs+803)
|
||||
#define FOREGROUND_NAME (ocserv_opt_strs+832)
|
||||
#define FOREGROUND_name (ocserv_opt_strs+843)
|
||||
#define FOREGROUND_FLAGS (OPTST_DISABLED)
|
||||
|
||||
/*
|
||||
* config option description:
|
||||
*/
|
||||
#define CONFIG_DESC (ocserv_opt_strs+854)
|
||||
#define CONFIG_NAME (ocserv_opt_strs+889)
|
||||
#define CONFIG_name (ocserv_opt_strs+896)
|
||||
#define CONFIG_FLAGS (OPTST_DISABLED \
|
||||
| OPTST_SET_ARGTYPE(OPARG_TYPE_FILE))
|
||||
|
||||
/*
|
||||
* Help/More_Help option descriptions:
|
||||
*/
|
||||
#define HELP_DESC (ocserv_opt_strs+903)
|
||||
#define HELP_name (ocserv_opt_strs+947)
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
#define MORE_HELP_DESC (ocserv_opt_strs+952)
|
||||
#define MORE_HELP_name (ocserv_opt_strs+997)
|
||||
#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
|
||||
#else
|
||||
#define MORE_HELP_DESC NULL
|
||||
#define MORE_HELP_name NULL
|
||||
#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
|
||||
#endif
|
||||
/*
|
||||
* Declare option callback procedures
|
||||
*/
|
||||
extern tOptProc
|
||||
optionBooleanVal, optionNestedVal, optionNumericVal,
|
||||
optionPagedUsage, optionPrintVersion, optionResetOpt,
|
||||
optionStackArg, optionTimeDate, optionTimeVal,
|
||||
optionUnstackArg, optionVendorOption;
|
||||
static tOptProc
|
||||
doOptConfig, doUsageOpt;
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/**
|
||||
* Define the ocserv Option Descriptions.
|
||||
* This is an array of OPTION_CT entries, one for each
|
||||
* option that the ocserv program responds to.
|
||||
*/
|
||||
static tOptDesc optDesc[OPTION_CT] = {
|
||||
{ /* entry idx, value */ 0, VALUE_OPT_FOREGROUND,
|
||||
/* equiv idx, value */ 0, VALUE_OPT_FOREGROUND,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ FOREGROUND_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL }, /* --foreground */
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ NULL,
|
||||
/* desc, NAME, name */ FOREGROUND_DESC, FOREGROUND_NAME, FOREGROUND_name,
|
||||
/* disablement strs */ NULL, NULL },
|
||||
|
||||
{ /* entry idx, value */ 1, VALUE_OPT_CONFIG,
|
||||
/* equiv idx, value */ 1, VALUE_OPT_CONFIG,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ CONFIG_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL }, /* --config */
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ doOptConfig,
|
||||
/* desc, NAME, name */ CONFIG_DESC, CONFIG_NAME, CONFIG_name,
|
||||
/* disablement strs */ NULL, NULL },
|
||||
|
||||
{ /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP,
|
||||
/* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ OPTST_IMM | OPTST_NO_INIT, 0,
|
||||
/* last opt argumnt */ { NULL },
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ doUsageOpt,
|
||||
/* desc, NAME, name */ HELP_DESC, NULL, HELP_name,
|
||||
/* disablement strs */ NULL, NULL },
|
||||
|
||||
{ /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP,
|
||||
/* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP,
|
||||
/* equivalenced to */ NO_EQUIVALENT,
|
||||
/* min, max, act ct */ 0, 1, 0,
|
||||
/* opt state flags */ MORE_HELP_FLAGS, 0,
|
||||
/* last opt argumnt */ { NULL },
|
||||
/* arg list/cookie */ NULL,
|
||||
/* must/cannot opts */ NULL, NULL,
|
||||
/* option proc */ optionPagedUsage,
|
||||
/* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name,
|
||||
/* disablement strs */ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Define the ocserv Option Environment
|
||||
*/
|
||||
#define zPROGNAME (ocserv_opt_strs+1007)
|
||||
#define zUsageTitle (ocserv_opt_strs+1014)
|
||||
#define zRcName NULL
|
||||
#define apzHomeList NULL
|
||||
#define zBugsAddr (ocserv_opt_strs+1100)
|
||||
#define zExplain (ocserv_opt_strs+1116)
|
||||
#define zDetail (ocserv_opt_strs+1119)
|
||||
#define zFullVersion (NULL)
|
||||
/* extracted from optcode.tlib near line 350 */
|
||||
|
||||
#if defined(ENABLE_NLS)
|
||||
# define OPTPROC_BASE OPTPROC_TRANSLATE | OPTPROC_NXLAT_OPT
|
||||
static tOptionXlateProc translate_option_strings;
|
||||
#else
|
||||
# define OPTPROC_BASE OPTPROC_NONE
|
||||
# define translate_option_strings NULL
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
|
||||
#define ocserv_full_usage (NULL)
|
||||
|
||||
#define ocserv_short_usage (ocserv_opt_strs+1145)
|
||||
|
||||
#endif /* not defined __doxygen__ */
|
||||
|
||||
/*
|
||||
* Create the static procedure(s) declared above.
|
||||
*/
|
||||
/**
|
||||
* The callout function that invokes the optionUsage function.
|
||||
*
|
||||
* @param pOptions the AutoOpts option description structure
|
||||
* @param pOptDesc the descriptor for the "help" (usage) option.
|
||||
* @noreturn
|
||||
*/
|
||||
static void
|
||||
doUsageOpt(tOptions * pOptions, tOptDesc * pOptDesc)
|
||||
{
|
||||
optionUsage(&ocservOptions, OCSERV_EXIT_SUCCESS);
|
||||
/* NOTREACHED */
|
||||
(void)pOptDesc;
|
||||
(void)pOptions;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
/**
|
||||
* Code to handle the config option.
|
||||
*
|
||||
* @param pOptions the ocserv options data structure
|
||||
* @param pOptDesc the option descriptor for this option.
|
||||
*/
|
||||
static void
|
||||
doOptConfig(tOptions* pOptions, tOptDesc* pOptDesc)
|
||||
{
|
||||
static teOptFileType const type =
|
||||
FTYPE_MODE_MUST_EXIST + FTYPE_MODE_NO_OPEN;
|
||||
static tuFileMode mode;
|
||||
#ifndef O_CLOEXEC
|
||||
# define O_CLOEXEC 0
|
||||
#endif
|
||||
mode.file_flags = O_CLOEXEC;
|
||||
|
||||
optionFileCheck(pOptions, pOptDesc, type, mode);
|
||||
}
|
||||
/* extracted from optmain.tlib near line 1113 */
|
||||
|
||||
/**
|
||||
* The directory containing the data associated with ocserv.
|
||||
*/
|
||||
#ifndef PKGDATADIR
|
||||
# define PKGDATADIR ""
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Information about the person or institution that packaged ocserv
|
||||
* for the current distribution.
|
||||
*/
|
||||
#ifndef WITH_PACKAGER
|
||||
# define ocserv_packager_info NULL
|
||||
#else
|
||||
static char const ocserv_packager_info[] =
|
||||
"Packaged by " WITH_PACKAGER
|
||||
|
||||
# ifdef WITH_PACKAGER_VERSION
|
||||
" ("WITH_PACKAGER_VERSION")"
|
||||
# endif
|
||||
|
||||
# ifdef WITH_PACKAGER_BUG_REPORTS
|
||||
"\nReport ocserv bugs to " WITH_PACKAGER_BUG_REPORTS
|
||||
# endif
|
||||
"\n";
|
||||
#endif
|
||||
#ifndef __doxygen__
|
||||
|
||||
#endif /* __doxygen__ */
|
||||
/**
|
||||
* The option definitions for ocserv. The one structure that
|
||||
* binds them all.
|
||||
*/
|
||||
tOptions ocservOptions = {
|
||||
OPTIONS_STRUCT_VERSION,
|
||||
0, NULL, /* original argc + argv */
|
||||
( OPTPROC_BASE
|
||||
+ OPTPROC_ERRSTOP
|
||||
+ OPTPROC_SHORTOPT
|
||||
+ OPTPROC_LONGOPT
|
||||
+ OPTPROC_NO_REQ_OPT
|
||||
+ OPTPROC_NO_ARGS
|
||||
+ OPTPROC_GNUUSAGE
|
||||
+ OPTPROC_MISUSE ),
|
||||
0, NULL, /* current option index, current option */
|
||||
NULL, NULL, zPROGNAME,
|
||||
zRcName, zCopyright, zLicenseDescrip,
|
||||
zFullVersion, apzHomeList, zUsageTitle,
|
||||
zExplain, zDetail, optDesc,
|
||||
zBugsAddr, /* address to send bugs to */
|
||||
NULL, NULL, /* extensions/saved state */
|
||||
optionUsage, /* usage procedure */
|
||||
translate_option_strings, /* translation procedure */
|
||||
/*
|
||||
* Indexes to special options
|
||||
*/
|
||||
{ INDEX_OPT_MORE_HELP, /* more-help option index */
|
||||
NO_EQUIVALENT, /* save option index */
|
||||
NO_EQUIVALENT, /* '-#' option index */
|
||||
NO_EQUIVALENT /* index of default opt */
|
||||
},
|
||||
4 /* full option count */, 2 /* user option count */,
|
||||
ocserv_full_usage, ocserv_short_usage,
|
||||
NULL, NULL,
|
||||
PKGDATADIR, ocserv_packager_info
|
||||
};
|
||||
|
||||
#if ENABLE_NLS
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <autoopts/usage-txt.h>
|
||||
|
||||
static char* AO_gettext(char const* pz);
|
||||
static void coerce_it(void** s);
|
||||
|
||||
/**
|
||||
* AutoGen specific wrapper function for gettext.
|
||||
* It relies on the macro _() to convert from English to the target
|
||||
* language, then strdup-duplicates the result string.
|
||||
*
|
||||
* @param[in] pz the input text used as a lookup key.
|
||||
* @returns the translated text (if there is one),
|
||||
* or the original text (if not).
|
||||
*/
|
||||
static char *
|
||||
AO_gettext(char const* pz)
|
||||
{
|
||||
char* pzRes;
|
||||
if (pz == NULL)
|
||||
return NULL;
|
||||
pzRes = _(pz);
|
||||
if (pzRes == pz)
|
||||
return pzRes;
|
||||
pzRes = strdup(pzRes);
|
||||
if (pzRes == NULL) {
|
||||
fputs(_("No memory for duping translated strings\n"), stderr);
|
||||
exit(OCSERV_EXIT_FAILURE);
|
||||
}
|
||||
return pzRes;
|
||||
}
|
||||
|
||||
static void coerce_it(void** s) { *s = AO_gettext(*s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate all the translatable strings in the ocservOptions
|
||||
* structure defined above. This is done only once.
|
||||
*/
|
||||
static void
|
||||
translate_option_strings(void)
|
||||
{
|
||||
tOptions * const pOpt = &ocservOptions;
|
||||
|
||||
/*
|
||||
* Guard against re-translation. It won't work. The strings will have
|
||||
* been changed by the first pass through this code. One shot only.
|
||||
*/
|
||||
if (option_usage_text.field_ct != 0) {
|
||||
/*
|
||||
* Do the translations. The first pointer follows the field count
|
||||
* field. The field count field is the size of a pointer.
|
||||
*/
|
||||
tOptDesc * pOD = pOpt->pOptDesc;
|
||||
char ** ppz = (char**)(void*)&(option_usage_text);
|
||||
int ix = option_usage_text.field_ct;
|
||||
|
||||
do {
|
||||
ppz++;
|
||||
*ppz = AO_gettext(*ppz);
|
||||
} while (--ix > 0);
|
||||
|
||||
coerce_it((void*)&(pOpt->pzCopyright));
|
||||
coerce_it((void*)&(pOpt->pzCopyNotice));
|
||||
coerce_it((void*)&(pOpt->pzFullVersion));
|
||||
coerce_it((void*)&(pOpt->pzUsageTitle));
|
||||
coerce_it((void*)&(pOpt->pzExplain));
|
||||
coerce_it((void*)&(pOpt->pzDetail));
|
||||
coerce_it((void*)&(pOpt->pzPackager));
|
||||
coerce_it((void*)&(pOpt->pzShortUsage));
|
||||
option_usage_text.field_ct = 0;
|
||||
|
||||
for (ix = pOpt->optCt; ix > 0; ix--, pOD++)
|
||||
coerce_it((void*)&(pOD->pzText));
|
||||
}
|
||||
|
||||
if ((pOpt->fOptSet & OPTPROC_NXLAT_OPT_CFG) == 0) {
|
||||
tOptDesc * pOD = pOpt->pOptDesc;
|
||||
int ix;
|
||||
|
||||
for (ix = pOpt->optCt; ix > 0; ix--, pOD++) {
|
||||
coerce_it((void*)&(pOD->pz_Name));
|
||||
coerce_it((void*)&(pOD->pz_DisableName));
|
||||
coerce_it((void*)&(pOD->pz_DisablePfx));
|
||||
}
|
||||
/* prevent re-translation */
|
||||
ocservOptions.fOptSet |= OPTPROC_NXLAT_OPT_CFG | OPTPROC_NXLAT_OPT;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/* ocserv-args.c ends here */
|
||||
@@ -0,0 +1,116 @@
|
||||
AutoGen Definitions options;
|
||||
prog-name = ocserv;
|
||||
prog-title = "OpenConnect server";
|
||||
prog-desc = "OpenConnect VPN server.";
|
||||
disable-save;
|
||||
no-xlate = opt;
|
||||
gnu-usage;
|
||||
config-header = config.h;
|
||||
long-opts;
|
||||
no-misuse-usage;
|
||||
short-usage = "Usage: ocserv [options]\nocserv --help for usage instructions.\n";
|
||||
explain = "";
|
||||
detail = "OpenConnect VPN server.";
|
||||
|
||||
copyright = {
|
||||
date = "2013";
|
||||
owner = "Nikos Mavrogiannopoulos";
|
||||
author = "Nikos Mavrogiannopoulos";
|
||||
eaddr = "nmav@gnutls.org";
|
||||
type = gplv2;
|
||||
};
|
||||
|
||||
flag = {
|
||||
name = foreground;
|
||||
value = f;
|
||||
descrip = "Do not fork into background.";
|
||||
doc = "";
|
||||
};
|
||||
|
||||
flag = {
|
||||
name = config;
|
||||
value = c;
|
||||
arg-type = file;
|
||||
file-exists = yes;
|
||||
descrip = "Configuration file for the server.";
|
||||
doc = "";
|
||||
};
|
||||
|
||||
help-value = h;
|
||||
|
||||
doc-section = {
|
||||
ds-type = 'FILES';
|
||||
ds-format = 'texi';
|
||||
ds-text = <<-_EOT_
|
||||
@subheading ocserv's configuration file format
|
||||
|
||||
An example configuration file follows.
|
||||
|
||||
@example
|
||||
|
||||
# User authentication method
|
||||
# Options certificate, pam.
|
||||
#auth = "pam,certificate"
|
||||
auth = "pam"
|
||||
|
||||
# TCP port number
|
||||
tcp-port = 3333
|
||||
|
||||
# UDP port number
|
||||
udp-port = 3334
|
||||
|
||||
# The key and the certificates of the server
|
||||
server-cert = /path/to/cert.pem
|
||||
server-key = /path/to/key.pem
|
||||
|
||||
# The Certificate Authority that will be used
|
||||
# to verify clients if certificate authentication
|
||||
# is set.
|
||||
#ca-cert = /path/to/ca.pem
|
||||
|
||||
# A revocation list of ca-cert is set
|
||||
#crl = /path/to/crl.pem
|
||||
|
||||
# GnuTLS priority string
|
||||
tls-priorities = "PERFORMANCE:%SERVER_PRECEDENCE"
|
||||
|
||||
# The default server directory
|
||||
#chroot-dir = /path/to/chroot
|
||||
|
||||
# Cookie validity time (in seconds)
|
||||
# Once a client is authenticated he's provided a cookie with
|
||||
# which he can reconnect. This option sets the maximum lifetime
|
||||
# of that cookie.
|
||||
cookie-validity = 14400
|
||||
|
||||
# Cookie database file. Where to store the cookies.
|
||||
cookie-db = /path/to/db
|
||||
|
||||
run-as-user = nobody
|
||||
run-as-group = nogroup
|
||||
|
||||
# Network settings
|
||||
|
||||
device = vpns
|
||||
|
||||
ipv4-address = 192.168.1.0
|
||||
ipv4-mask = 255.255.255.0
|
||||
# Use the keywork local to advertize the local P-t-P address as DNS server
|
||||
# network-ipv4-dns = 192.168.2.1
|
||||
ipv4-dns = local
|
||||
|
||||
#ipv6-address =
|
||||
#ipv6-mask =
|
||||
#ipv6-dns =
|
||||
|
||||
# Leave empty to assign the default MTU of the device
|
||||
# mtu =
|
||||
|
||||
route = 192.168.2.0/255.255.255.0
|
||||
route = 192.168.5.0/255.255.255.0
|
||||
|
||||
@end example
|
||||
|
||||
_EOT_;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/* -*- buffer-read-only: t -*- vi: set ro:
|
||||
*
|
||||
* DO NOT EDIT THIS FILE (ocserv-args.h)
|
||||
*
|
||||
* It has been AutoGen-ed January 30, 2013 at 01:39:04 AM by AutoGen 5.16
|
||||
* From the definitions ocserv-args.def
|
||||
* and the template file options
|
||||
*
|
||||
* Generated from AutoOpts 36:4:11 templates.
|
||||
*
|
||||
* AutoOpts is a copyrighted work. This header file is not encumbered
|
||||
* by AutoOpts licensing, but is provided under the licensing terms chosen
|
||||
* by the ocserv author or copyright holder. AutoOpts is
|
||||
* licensed under the terms of the LGPL. The redistributable library
|
||||
* (``libopts'') is licensed under the terms of either the LGPL or, at the
|
||||
* users discretion, the BSD license. See the AutoOpts and/or libopts sources
|
||||
* for details.
|
||||
*
|
||||
* The ocserv program is copyrighted and licensed
|
||||
* under the following terms:
|
||||
*
|
||||
* Copyright (C) 2013 Nikos Mavrogiannopoulos, all rights reserved.
|
||||
* This is free software. It is licensed for use, modification and
|
||||
* redistribution under the terms of the
|
||||
* GNU General Public License, version 2 <http://gnu.org/licenses/gpl.html>
|
||||
*
|
||||
* ocserv is free software: you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* ocserv is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License,
|
||||
* version 2, along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
* This file contains the programmatic interface to the Automated
|
||||
* Options generated for the ocserv program.
|
||||
* These macros are documented in the AutoGen info file in the
|
||||
* "AutoOpts" chapter. Please refer to that doc for usage help.
|
||||
*/
|
||||
#ifndef AUTOOPTS_OCSERV_ARGS_H_GUARD
|
||||
#define AUTOOPTS_OCSERV_ARGS_H_GUARD 1
|
||||
#include "config.h"
|
||||
#include <autoopts/options.h>
|
||||
|
||||
/*
|
||||
* Ensure that the library used for compiling this generated header is at
|
||||
* least as new as the version current when the header template was released
|
||||
* (not counting patch version increments). Also ensure that the oldest
|
||||
* tolerable version is at least as old as what was current when the header
|
||||
* template was released.
|
||||
*/
|
||||
#define AO_TEMPLATE_VERSION 147460
|
||||
#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \
|
||||
|| (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION)
|
||||
# error option template version mismatches autoopts/options.h header
|
||||
Choke Me.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumeration of each option:
|
||||
*/
|
||||
typedef enum {
|
||||
INDEX_OPT_FOREGROUND = 0,
|
||||
INDEX_OPT_CONFIG = 1,
|
||||
INDEX_OPT_HELP = 2,
|
||||
INDEX_OPT_MORE_HELP = 3
|
||||
} teOptIndex;
|
||||
|
||||
#define OPTION_CT 4
|
||||
|
||||
/*
|
||||
* Interface defines for all options. Replace "n" with the UPPER_CASED
|
||||
* option name (as in the teOptIndex enumeration above).
|
||||
* e.g. HAVE_OPT(FOREGROUND)
|
||||
*/
|
||||
#define DESC(n) (ocservOptions.pOptDesc[INDEX_OPT_## n])
|
||||
#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n)))
|
||||
#define OPT_ARG(n) (DESC(n).optArg.argString)
|
||||
#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK)
|
||||
#define COUNT_OPT(n) (DESC(n).optOccCt)
|
||||
#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n)))
|
||||
#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n)))
|
||||
#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n)))
|
||||
#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt)
|
||||
#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs)
|
||||
#define CLEAR_OPT(n) STMTS( \
|
||||
DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \
|
||||
if ((DESC(n).fOptState & OPTST_INITENABLED) == 0) \
|
||||
DESC(n).fOptState |= OPTST_DISABLED; \
|
||||
DESC(n).optCookie = NULL )
|
||||
|
||||
/* * * * * *
|
||||
*
|
||||
* Enumeration of ocserv exit codes
|
||||
*/
|
||||
typedef enum {
|
||||
OCSERV_EXIT_SUCCESS = 0,
|
||||
OCSERV_EXIT_FAILURE = 1,
|
||||
OCSERV_EXIT_LIBOPTS_FAILURE = 70
|
||||
} ocserv_exit_code_t;
|
||||
/* * * * * *
|
||||
*
|
||||
* Interface defines for specific options.
|
||||
*/
|
||||
#define VALUE_OPT_FOREGROUND 'f'
|
||||
#define VALUE_OPT_CONFIG 'c'
|
||||
#define VALUE_OPT_HELP 'h'
|
||||
#define VALUE_OPT_MORE_HELP '!'
|
||||
/*
|
||||
* Interface defines not associated with particular options
|
||||
*/
|
||||
#define ERRSKIP_OPTERR STMTS(ocservOptions.fOptSet &= ~OPTPROC_ERRSTOP)
|
||||
#define ERRSTOP_OPTERR STMTS(ocservOptions.fOptSet |= OPTPROC_ERRSTOP)
|
||||
#define RESTART_OPT(n) STMTS( \
|
||||
ocservOptions.curOptIdx = (n); \
|
||||
ocservOptions.pzCurOpt = NULL)
|
||||
#define START_OPT RESTART_OPT(1)
|
||||
#define USAGE(c) (*ocservOptions.pUsageProc)(&ocservOptions, c)
|
||||
/* extracted from opthead.tlib near line 484 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* * * * * *
|
||||
*
|
||||
* Declare the ocserv option descriptor.
|
||||
*/
|
||||
extern tOptions ocservOptions;
|
||||
|
||||
#if defined(ENABLE_NLS)
|
||||
# ifndef _
|
||||
# include <stdio.h>
|
||||
static inline char* aoGetsText(char const* pz) {
|
||||
if (pz == NULL) return NULL;
|
||||
return (char*)gettext(pz);
|
||||
}
|
||||
# define _(s) aoGetsText(s)
|
||||
# endif /* _() */
|
||||
|
||||
# define OPT_NO_XLAT_CFG_NAMES STMTS(ocservOptions.fOptSet |= \
|
||||
OPTPROC_NXLAT_OPT_CFG;)
|
||||
# define OPT_NO_XLAT_OPT_NAMES STMTS(ocservOptions.fOptSet |= \
|
||||
OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;)
|
||||
|
||||
# define OPT_XLAT_CFG_NAMES STMTS(ocservOptions.fOptSet &= \
|
||||
~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);)
|
||||
# define OPT_XLAT_OPT_NAMES STMTS(ocservOptions.fOptSet &= \
|
||||
~OPTPROC_NXLAT_OPT;)
|
||||
|
||||
#else /* ENABLE_NLS */
|
||||
# define OPT_NO_XLAT_CFG_NAMES
|
||||
# define OPT_NO_XLAT_OPT_NAMES
|
||||
|
||||
# define OPT_XLAT_CFG_NAMES
|
||||
# define OPT_XLAT_OPT_NAMES
|
||||
|
||||
# ifndef _
|
||||
# define _(_s) _s
|
||||
# endif
|
||||
#endif /* ENABLE_NLS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* AUTOOPTS_OCSERV_ARGS_H_GUARD */
|
||||
/* ocserv-args.h ends here */
|
||||
@@ -43,7 +43,6 @@ struct vpn_st {
|
||||
|
||||
struct cfg_st {
|
||||
const char *name;
|
||||
unsigned workers;
|
||||
unsigned int port;
|
||||
const char *cert;
|
||||
const char *key;
|
||||
@@ -52,10 +51,11 @@ struct cfg_st {
|
||||
const char *cert_user_oid; /* The OID that will be used to extract the username */
|
||||
gnutls_certificate_request_t cert_req;
|
||||
const char *priorities;
|
||||
const char *root_dir; /* where the xml files are served from */
|
||||
const char *chroot_dir; /* where the xml files are served from */
|
||||
unsigned int auth_types; /* or'ed sequence of AUTH_TYPE */
|
||||
time_t cookie_validity; /* in seconds */
|
||||
const char *db_file;
|
||||
unsigned foreground;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
@@ -134,5 +134,6 @@ const char *human_addr(const struct sockaddr *sa, socklen_t salen,
|
||||
int __attribute__ ((format(printf, 3, 4)))
|
||||
oclog(const worker_st * server, int priority, const char *fmt, ...);
|
||||
|
||||
int cmd_parser (int argc, char **argv, struct cfg_st* config);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user