use autogen for command line options

This commit is contained in:
Nikos Mavrogiannopoulos
2013-01-30 01:39:14 +01:00
parent 18becb9640
commit 8c2735d1e1
70 changed files with 19874 additions and 11 deletions
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+6
View File
@@ -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
+674
View File
@@ -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>.
+165
View File
@@ -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.
+26
View File
@@ -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.
View File
+26
View File
@@ -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
View File
@@ -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.
+491
View File
@@ -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
View File
@@ -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 */
+323
View File
@@ -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 */
+251
View File
@@ -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 */
+729
View File
@@ -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 */
+335
View File
@@ -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
+50
View File
@@ -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 */
+433
View File
@@ -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 */
+94
View File
@@ -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
View File
@@ -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;
}
+401
View File
@@ -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 */
+334
View File
@@ -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 */
+60
View File
@@ -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
}
+60
View File
@@ -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 */
+19
View File
@@ -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;
}
+145
View File
@@ -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 */
+1429
View File
File diff suppressed because it is too large Load Diff
+311
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+452
View File
@@ -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 */
+178
View File
@@ -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 */
+45
View File
@@ -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
View File
@@ -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 */
+583
View File
@@ -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
])
+29
View File
@@ -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])
+838
View File
@@ -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 */
+849
View File
@@ -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 */
+165
View File
@@ -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 */
+601
View File
@@ -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 */
+90
View File
@@ -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 */
+132
View File
@@ -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
View File
@@ -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 */
+361
View File
@@ -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
View File
@@ -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 */
+228
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
+267
View File
@@ -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 */
+370
View File
@@ -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
View File
@@ -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 */
+333
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+123
View File
@@ -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;
}
+25
View File
@@ -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 */
+211
View File
@@ -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 */
+114
View File
@@ -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;
}
+22
View File
@@ -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
View File
@@ -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
+49
View File
@@ -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
View File
@@ -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 */
+438
View File
@@ -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 */
+116
View File
@@ -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_;
};
+174
View File
@@ -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 */
+3 -2
View File
@@ -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