copy from intranet.

This commit is contained in:
lijia
2019-07-10 17:54:02 +08:00
commit f36a4fca25
353 changed files with 130721 additions and 0 deletions

234
INSTALL Normal file
View File

@@ -0,0 +1,234 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006 Free Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

69
Makefile.am Normal file
View File

@@ -0,0 +1,69 @@
# $Id$
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4 -I libopts/m4
if NEED_LIBOPTS
SUBDIRS = scripts lib $(LIBOPTS_DIR) src
else
SUBDIRS = scripts lib src
endif
DIST_SUBDIRS = scripts lib libopts src docs test
.PHONY: manpages docs test man2html
dist-hook: version manpages update
update:
svn update
DOCS_DIR = $(top_builddir)/docs
manpages:
cd src && make manpages
docs: manpages
echo Making docs in $(DOCS_DIR)
cd $(DOCS_DIR) && make docs
clean-docs:
cd $(DOCS_DIR) && make clean-docs
postweb: docs doxygen
cd $(DOCS_DIR) && make postweb
TEST_DIR = $(top_builddir)/test
autoopts:
cd src && make autoopts
test:
echo Making test in $(TEST_DIR)
cd $(TEST_DIR) && make test
dlt_names:
cat @SAVEFILE_C@ | $(top_builddir)/scripts/dlt2name.pl src/dlt_names.h
version:
-rm -f src/common/svn_version.c
cd src/common && make svn_version.c
distclean-local:
-rm -rf autom4te.cache doxygen
doxygen: version
doxygen doxygen.cfg
ncc:
CC=ncc make
MOSTLYCLEANFILES = tcpreplay.spec *~
DISTCLEANFILES = .tm_project.cache stamp-h1 *.tar.*
MAINTAINERCLEANFILES = Makefile.in configure *.bak
EXTRA_DIST = doxygen.cfg.in autogen.sh \
m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 \
m4/ltversion.m4 m4/lt~obsolete.m4

797
Makefile.in Normal file
View File

@@ -0,0 +1,797 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/doxygen.cfg.in \
$(top_srcdir)/configure INSTALL config/compile \
config/config.guess config/config.sub config/depcomp \
config/install-sh config/ltmain.sh config/missing \
config/mkinstalldirs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES = doxygen.cfg
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d "$(distdir)" \
|| { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr "$(distdir)"; }; }
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
# $Id$
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4 -I libopts/m4
@NEED_LIBOPTS_FALSE@SUBDIRS = scripts lib src
@NEED_LIBOPTS_TRUE@SUBDIRS = scripts lib $(LIBOPTS_DIR) src
DIST_SUBDIRS = scripts lib libopts src docs test
DOCS_DIR = $(top_builddir)/docs
TEST_DIR = $(top_builddir)/test
MOSTLYCLEANFILES = tcpreplay.spec *~
DISTCLEANFILES = .tm_project.cache stamp-h1 *.tar.*
MAINTAINERCLEANFILES = Makefile.in configure *.bak
EXTRA_DIST = doxygen.cfg.in autogen.sh \
m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 \
m4/ltversion.m4 m4/lt~obsolete.m4
all: all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
doxygen.cfg: $(top_builddir)/config.status $(srcdir)/doxygen.cfg.in
cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@$(am__cd) '$(distuninstallcheck_dir)' \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-local distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
dist-gzip dist-hook dist-lzma dist-shar dist-tarZ dist-xz \
dist-zip distcheck distclean distclean-generic \
distclean-libtool distclean-local distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am
.PHONY: manpages docs test man2html
dist-hook: version manpages update
update:
svn update
manpages:
cd src && make manpages
docs: manpages
echo Making docs in $(DOCS_DIR)
cd $(DOCS_DIR) && make docs
clean-docs:
cd $(DOCS_DIR) && make clean-docs
postweb: docs doxygen
cd $(DOCS_DIR) && make postweb
autoopts:
cd src && make autoopts
test:
echo Making test in $(TEST_DIR)
cd $(TEST_DIR) && make test
dlt_names:
cat @SAVEFILE_C@ | $(top_builddir)/scripts/dlt2name.pl src/dlt_names.h
version:
-rm -f src/common/svn_version.c
cd src/common && make svn_version.c
distclean-local:
-rm -rf autom4te.cache doxygen
doxygen: version
doxygen doxygen.cfg
ncc:
CC=ncc make
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

77
README.md Normal file
View File

@@ -0,0 +1,77 @@
/*
Version Maintenance : LiJia(lijia01@iie.ac.cn)
Create Time : 2013-06-06
Latest Time : 2018-06-12
tcpburst-2.1:
支持vxlan封装格式, 将已有的pcap包内容封装在vxlan数据包内, 用于模拟测试串联模式下的平台处理流量情况.
tcpburst-2.0:
支持marsio发包接口.
tcpburst-1.2:
20161214, 增加对GRE, 6over4, IPinIP等隧道协议的支持.
tcpburst-1.1
修改流放大部分算法.
tcpburst-1.0:
基于标准tcpreplay增加基于TCP或UDP流的放大功能可用于大流量包回放、性能测试等.
修改背景:
标准的tcpreplay读包速率受硬盘传输速度影响一般最高在600Mbps左右.
本程序在tcpreplay的基础上针对上述瓶颈做了一些修改:
每读到一个TCP或UDP包原始包原样转发然后对其IP地址进行修改后再次发送N个包
这样捕包时会得到不同四元组、但应用层数据相同的流,达到流量放大目的.
功能介绍:
例:
原始TCP流 1.1.1.1:12345<-->10.10.10.10:80
假设流放大倍数=4则新回放的包中包含如下TCP流:
1.1.1.1:12345<-->10.10.10.10:80
2.1.1.1:12345<-->9.10.10.10:80
3.1.1.1:12345<-->8.10.10.10:80
4.1.1.1:12345<-->7.10.10.10:80
5.1.1.1:12345<--->6.10.10.10:80
使用说明:
configure
make
make install
在标准tcpreplay基础上新增加了2个参数:
-m, --stream-multiple=num Replay streams at a given multiple流放大倍数;
-d, --packet-distance=num The distance between raw packet and fake replay packet原始包与虚假回放包的间距.
packet-distance的作用:
假设原始流CPU近似占用率如下:
cpu
20| /\
15| / \
10| / \ /\
05| / \ / \
0|--/--------\/----\-----time
设参数stream-multiple=4, packet-distance=0 CPU近似占用率(注意纵坐标的变化!!!):
cpu
80| /\
40| / \
60| / \ /\
20| / \ / \
0|--/--------\/----\-----time
(因为只改变了四元组,应用层数据是相同的,包间距=0的话即同样的应用层数据会在短时间内重复处理N次)
设参数stream-multiple=4, packet-distance=100有可能会得到这样的CPU占用率:
cpu
40| /\/\/\/\/\/\/\/\/\/\/
30|
20|
10|
0|---------------------- time
所以,使用流放大功能的话,强烈推荐加-d选项合理设置packet-distance的值
*/

48
README.tcpreplay Normal file
View File

@@ -0,0 +1,48 @@
$Id: README 1796 2007-04-11 04:55:14Z aturner $
[Please note that licensing, compiling, usage and other documentation can be
found in the docs subdirectory.]
If you have a question or think you are experiancing a bug, it is important
that you provide enough information for us to help you. Failure to provide
enough information will likely cause your email to be ignored or get an
annoyed reply from the author.
If your problem has to do with COMPILING tcpreplay:
- Version of tcpreplay you are trying to compile
- Platform (Red Hat Linux 9 on x86, Solaris 7 on SPARC, OS X on PPC, etc)
- ./configure arguments
- Contents of config.log
- Output from 'make'
- Any additional information you think that would be useful.
If your problem has to do with RUNNING tcpreplay or one of the sub-tools:
- Version information (output of -V)
- Command line used (options and arguments)
- Platform (Red Hat Linux 9 on Intel, Solaris 7 on SPARC, etc)
- Make & model of the network card(s) and driver(s) version
- Error message (if available) and/or description of problem
- If possible, attach the pcap file used (compressed with bzip2 or gzip
preferred)
- The core dump or backtrace if available
- Detailed description of your problem or what you are trying to accomplish
Note: The author of tcpreplay primarily uses OS X; hence, if you're reporting
an issue on another platform, it is important that you give very detailed
information as I may not be able to reproduce your issue.
You are also strongly encouraged to read the extensive documentation (man
pages, FAQ, documents in /docs and email list archives) BEFORE posting to the
tcpreplay-users email list:
http://lists.sourceforge.net/lists/listinfo/tcpreplay-users
Lastly, please don't email the author directly with your questions. Doing so
prevents others from potentially helping you and your question/answer from
showing up in the list archives.
Thanks,
Aaron (tcpreplay author)
PS:
This product includes software developed by the University of
California, Berkeley, Lawrence Berkeley Laboratory and its contributors.

9013
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

14
autogen.sh Normal file
View File

@@ -0,0 +1,14 @@
#!/bin/sh
rm -f config/config.guess config/config.sub config/ltmain.sh 2>/dev/null
rm -f aclocal.m4 2>/dev/null
aclocal -I libopts/m4/
if test -x "`which libtoolize`" ; then
libtoolize --copy
else
# Necessary under OS X
glibtoolize --copy
fi
autoheader
automake --add-missing --copy
autoconf

21
compile_cn.txt Normal file
View File

@@ -0,0 +1,21 @@
/*
make clean
make distclean
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>configure.ac<61><63>34<33><34>:
#CFLAGS="${CFLAGS} -Wall -O3 -std=gnu99"
<EFBFBD><EFBFBD>Ϊ:
CFLAGS="${CFLAGS} -Wall -g -std=gnu99 -DTCPBURST=1"
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD>DEBUG<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ʽʹ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ
CFLAGS="${CFLAGS} -Wall -O3 -std=gnu99 -DTCPBURST=1"
ʹ<EFBFBD><EFBFBD>MARSIOģʽ<EFBFBD><EFBFBD>
CFLAGS="${CFLAGS} -Wall -O3 -std=gnu99 -DTCPBURST=1 -DMARSIO=1 -lmarsio"
./configure
make
make install
*/

136
config/compile Normal file
View File

@@ -0,0 +1,136 @@
#! /bin/sh
# Wrapper for compilers which do not understand `-c -o'.
scriptversion=2003-11-09.00
# Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# 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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand `-c -o'.
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file `INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "compile $scriptversion"
exit 0
;;
esac
prog=$1
shift
ofile=
cfile=
args=
while test $# -gt 0; do
case "$1" in
-o)
# configure might choose to run compile as `compile cc -o foo foo.c'.
# So we do something ugly here.
ofile=$2
shift
case "$ofile" in
*.o | *.obj)
;;
*)
args="$args -o $ofile"
ofile=
;;
esac
;;
*.c)
cfile=$1
args="$args $1"
;;
*)
args="$args $1"
;;
esac
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no `-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# `.c' file was seen then we are probably linking. That is also
# ok.
exec "$prog" $args
fi
# Name of file we expect compiler to create.
cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
# Create the lock directory.
# Note: use `[/.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d
while true; do
if mkdir $lockdir > /dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir $lockdir; exit 1" 1 2 15
# Run the compile.
"$prog" $args
status=$?
if test -f "$cofile"; then
mv "$cofile" "$ofile"
fi
rmdir $lockdir
exit $status
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

1501
config/config.guess vendored Normal file

File diff suppressed because it is too large Load Diff

1705
config/config.sub vendored Normal file

File diff suppressed because it is too large Load Diff

526
config/depcomp Normal file
View File

@@ -0,0 +1,526 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2004-04-25.13
# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
# 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, 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., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit 0
;;
-v | --v*)
echo "depcomp $scriptversion"
exit 0
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# `libtool' can also be set to `yes' or `no'.
if test -z "$depfile"; then
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
dir=`echo "$object" | sed 's,/.*$,/,'`
if test "$dir" = "$object"; then
dir=
fi
# FIXME: should be _deps on DOS.
depfile="$dir.deps/$base"
fi
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# Dependencies are output in .lo.d with libtool 1.4.
# They are output in .o.d with libtool 1.5.
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir.libs/$base.o.d"
tmpdepfile3="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
tmpdepfile3="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
elif test -f "$tmpdepfile2"; then
tmpdepfile="$tmpdepfile2"
else
tmpdepfile="$tmpdepfile3"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

325
config/install-sh Normal file
View File

@@ -0,0 +1,325 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2004-04-01.17
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=
transform_arg=
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
usage="Usage: $0 [OPTION]... SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 -d DIRECTORIES...
In the first form, install SRCFILE to DSTFILE, removing SRCFILE by default.
In the second, create the directory path DIR.
Options:
-b=TRANSFORMBASENAME
-c copy source (using $cpprog) instead of moving (using $mvprog).
-d create directories instead of installing files.
-g GROUP $chgrp installed files to GROUP.
-m MODE $chmod installed files to MODE.
-o USER $chown installed files to USER.
-s strip installed files (using $stripprog).
-t=TRANSFORM
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit 0;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
--version) echo "$0 $scriptversion"; exit 0;;
*) # When -d is used, all remaining arguments are directories to create.
test -n "$dir_arg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
instcmd=:
chmodcmd=
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp" || lasterr=$?
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test ! -d "$pathcomp" && { (exit ${lasterr-1}); exit; }
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $instcmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
# If we're going to rename the final executable, determine the name now.
if test -z "$transformarg"; then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename \
| sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename.
test -z "$dstfile" && dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

8406
config/ltmain.sh Normal file

File diff suppressed because it is too large Load Diff

360
config/missing Normal file
View File

@@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2003-09-02.23
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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, 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., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

150
config/mkinstalldirs Normal file
View File

@@ -0,0 +1,150 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
scriptversion=2004-02-15.20
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit 0
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

23697
configure vendored Normal file

File diff suppressed because it is too large Load Diff

1255
configure.ac Normal file

File diff suppressed because it is too large Load Diff

379
docs/CHANGELOG Normal file
View File

@@ -0,0 +1,379 @@
$Id: CHANGELOG 2449 2010-04-04 06:39:38Z aturner $
04/04/2010 Version 3.4.4
- Set default timing method to either gtod or abstime (#404)
- Fix IPv6 parsing of CIDR's (#405)
- Add support for preloading the memory cache (#410)
- Generate more useful error when packets are too small (#411)
- Update to libopts/Autogen 5.9.9 (#412)
- Ship Win32Readme.txt file (#413)
- Update copyright notice to 2010 (#416)
- Dramatically enhance --portmap option (#417)
- Update autotools (#423)
- Add support for printing statistics periodically during the run (#424)
- Warn user when pcap snaplen < 65535 (#425)
- Add 802.1q processing support tcpprep (#428)
06/25/2009: Version 3.4.3
- Link libnl when newer versions of libpcap require it (#397)
- Ship m4 directory (#398)
- Upgrade to latest autotools scripts (#400)
- Fix error message when running autogen.sh (#401)
05/20/2009: Version 3.4.2
- Added extensive IPv6 support to tcprewrite & tcpreplay-edit (#11)
- Add IPv6 fragroute support (#388)
- Add IPv6 decoding support to tcpprep (#11)
- Fix compile time error in err.h (#390)
- Add --endpoints support in tcpreplay-edit (#393)
02/18/2009: Version 3.4.1
- Sendpacket method did not match documentation (#361)
- Fix compile issue on systems without err.h (#363)
- Fix tcpprep --mac not processing non-IPv4 packets (#369)
- Always build tcpreplay w/ editing features as tcpreplay-edit (#372)
- Fix potential tcpbridge issues under OS X & *BSD (#373)
- Fix crash on 4 byte strictly aligned systems (#377)
- Add MTU truncation to tcprewrite/tcpreplay-edit (#379)
01/15/2009: Version 3.4.0
- Add libdnet and remove libnet support for sending packets (#302)
- Fix numerous 802.11 decoder bugs (#325)
- Fix compile issue under Linux (#326)
- Fix Mbps/sec nonsense (#327)
- Fix tcprewrite crash when packets have no L3+ data (#328)
- Clean up err.c/err.h code and improve performance for non-debug builds (#331)
- Fix timesdiv() timer code (#332)
- Improve high-performance packet sending via multiple packets/interval (#334)
- Fix statistics report errors (#335)
- Fix BPF filters not being used in tcpbridge (#336)
- Improve tcpbridge performance (#337)
- Only use two libpcap handles for tcpbridge (#338)
- Fix autotools usage errors (#340)
- Clean up 'make test' results (#341)
- Update to AutoGen/AutoOpts 5.9.7 (#342)
- Fix compiler warnings from GCC 4.2 (#344)
- Fix numerous memory corruption bugs in libtcpedit DLT plugin code (#345)
- Add support for editing IPv4 TOS/DiffServ/ECN (#348)
- Update autotools to more recent versions (#349)
- Report injection method via -V (#352)
- Fix DLT_USER l2len check bug (#353)
- Replace man2html w/ groff (#354)
- Fix false pcap_inject() detection under Windows/Winpcap (#355)
- tcpbridge now builds under Win32/Cygwin
- libdnet is no longer an option for Win32/Cygwin (#57)
- tcpbridge now supports --listnics (#357)
06/20/2008: Version 3.3.2
- Fix (again) tcpbridge --unidir assert error (#308)
- Fix tcpbridge bug where all packets that were sent were all zeros
- Fix tcpbridge not honoring --include/exclude flags (#311)
- Fix ip_in_cidr() debug messages (#312)
- Report packets which have timestamps which go backwards in time (#315)
- Clean up --sleep-accel code to use options struct (#316)
- Remove really old and out of date RPM .spec file (#317)
- Warn when sending on non-Ethernet interface (#318)
- Re-enable tcpreplay --listnics (#319)
- Fix sendpacket always reporting using PF_PACKET, even when it doesn't (#322)
- Fix major packet timing issue under old versions of glibc (#324)
05/17/2008: Version 3.3.1
- Fix limitation of PF_PACKET only supporting Ethernet (#123)
- Fix (again) /dev/bpf detection in FreeBSD 8.0 (#292)
- Document building code from Subversion under Cygwin (#304)
- Fix --enable-force-* under Linux (#305)
- Fix tcpbridge --unidir assert error (#308)
05/04/2008: Version 3.3.0
- Improve tcpreplay timing accuracy between packets (#41)
- Add tcprewrite fragroute support (#42)
- Fix tcprewrite --efcs option (#277)
- Updated Win32/Cygwin documentation (#280)
- Add dmalloc support (#282)
- Fix tcpprep broken handling of VLAN tagged frames (#290)
- Fix tcprewrite crash when cache file has NO_SEND packets (#291)
- Fix /dev/bpf detection in FreeBSD 8.0 (#292)
- Add tcprewrite --ttl editing option (#294)
- Fix autoconf AM_PROG_CC_C_O warning (#295)
- Add tcpprep --reverse option to split by matching client addresses (#297)
- Update version of autoconf to 1.10.1 (#298)
- Improved GNU Autogen detection and warnings (#299)
- Track EAGAIN errors separately from ENOBUFS (#301)
- Automatically detect Winpcap on Cygwin (#303)
01/23/2008: Version 3.2.5
- Fix linker error with --enable-tcpreplay-edit and --enable-dynamic-link (#288)
- Fix compile errors with Sun Studio compiler (#286)
01/16/2008: Version 3.2.4
- Fix crash in tcpreplay when --enable-tcpreplay-edit (#281)
- Display if --enable-tcpreplay-edit in -V (#283)
11/01/2007: Version 3.2.3
- Fix compile issue under Linux and other OS's (#275)
10/31/2007: Version 3.2.2
- Enable source MAC spoofing for OS X (#142, #151)
* Tcpreplay now requires OS X 10.5 (Leopard)
- Fix crash/memory access error with tcpreplay -N (#273)
10/25/2007: Version 3.2.1
- Fix tcprewrite segfault in 'make test' under Linux (#200)
- Major performance improvement in tcpprep for large pcaps (#261)
- Fix strsignal already defined error under Cygwin/Windows (#199)
- Fix compile errors for older versions of GCC (#201)
- Remove flowreplay code (#262)
- Fix DLT rewrite code causing corrupted ethernet protocol type (#268)
- Try to fix inet_aton() issue under Solaris (#260)
08/26/2007: Version 3.2
- Return a more useful error message when tcpprep fails (#187)
- Add Tomahawk test tool client/server detection algorithm (#186)
- Improved AutoGen support (#191)
- Improved documentation (#164, #198)
- Added Doxygen markup (#176)
- configure now honors --with-tcpdump flag (#192)
- configure now defaults to --enable-64bits which breaks backwards
compatibility in certain situations. Use --disable-64bits if this
concerns you (#195)
- Use safe_free() to detect bugs earlier in development (#197)
07/19/2007: Version 3.1.1
- Upgrade libopts tearoff to 29:0:4 so that everyone else in the world can
compile tcpreplay (#189)
07/18/2007: Version 3.1.0
- Add tcprewrite --srcmap & --dstmap for rewriting only source or destination IP's (#185)
- ./configure now reports configuration at end (#155)
- Fix svn:keywords (#160)
- Optimize performance of dlt_en10mb plugin (#161)
- Performance improvements on strictly aligned systems (#162)
- Improve tcpprep error messages and handling (#163)
- Add support for warnings in libtcpedit (#165)
- Only use __attribute__((unused)) w/ GCC (#168)
- Fix compile issues under Solaris (#178)
- Gracefully handle systems w/o static libraries (#179)
- Fix segfault when using BPF filters (#182)
- Add additional DLT Plugins:
- 802.11 (#103)
- 802.11 w/ Radiotap (#177)
05/01/2007: Version 3.0.1
- Stop tcpreplay causing OS X WiFi from disassociating (#167)
- --pnat incorrectly matched all IP addresses (#170)
- Fix serious memory leak in core common library (#175)
- Fix tcprewrite --enet-vlan on little endian systems (#174)
- Bad pcap timestamps were causing excessive delays (#169)
- Code cleanup (#173)
04/20/2007: Version 3.0
- By default, no longer try to use libnet. You must now specify --enable-libnet (#148)
- Improve documentation (#30)
- General code cleanup (#47)
- Warn when GNU Autogen version < 5.9 (#153)
- Remove support for pcap_snapshot_override which was never added to libpcap (#140)
- Fix support for C99/GCC 4.3 "inline". Rely on -O3 for better performance. (#149)
- Prioritize 64 bit libraries over 32 bit counterparts (#150)
04/14/2007: Version 3.0.RC1
- Fix tcpbridge and make it compile by default (#15)
- Fix tcprewrite crash on little-endian systems (#127)
- Gracefully handle broken pcap files where the snaplen < caplen (#130)
- Note: Fix was made in libpcap and will be part of 0.9.6
- Fix numerous bugs with the sendpacket code (#137)
- Add optional support for editing packets with tcpreplay (#61)
- Fix 'make test' on little endian systems (#64)
- tcprewrite -s is no longer endian dependent (#65)
- /docs cleaned up (#66)
- Fix detection/compile of libpcap. Now support versions >= 0.7.2 (#80, #144)
- Add official support Cygwin/Win32 support (#110)
- Clean up libpcap version code (#111)
- Add support for interface alias names for Win32 (#113)
- Warn user on DLT miss-match (#125)
- Fix tcprewrite segfault with --fixlen=pad (#134)
- Add loop/cache support for better performance (#136)
- inline debugging code for better performance (#138)
- configure now supports selecting injection method (#139)
- Fix configure/compile errors under OpenBSD (#146)
- Add tcpbridge --verbose mode (#28)
- Fix compile issues under HP-UX & strictly aligned systems (#141)
- --enable-dynamic-link supports 64bit libraries (#143)
03/22/2007: Version 3.0.beta13
- Fixed detection of IPv4 packets in libtcpedit on little-endian boxes (#115, #116)
- Fixed TCP/UDP checksum calculation on little-endian boxes (#126)
- Added --quiet flag to tcpreplay for Lothar (#109)
- The --seed flag should now generate the same IPs on both little-endian & big-endian boxes (#65)
- The --skipl2broadcast flag now works as documented (#112)
- Adding L2 header for DLT_RAW encapsulated packets now works (#16)
- Clean up documentation (#66, #75)
- Start initial support for Win32 port (#110, #111)
- Finish DLT plugin rewrite (#82)
- Fix compile on systems without tcpdump installed
02/22/2007: Version 3.0.beta12
- Fix compile under RH ES 3.x (gcc 3.2.2) (#79)
- Fix compile on MIPS, ARM, HPPA, etc (#81, #88)
- Rewrite L2/DLT code in tcpedit/tcprewrite to be plugin based (#82)
- Create Ethernet Plugin (#99)
- Create User Plugin (#100)
- Create Cisco HDLC Plugin (#101)
- Create DLT_LINUX_SLL Plugin (#102)
- Create DLT_RAW Plugin (#104)
- Create DLT_NULL Plugin (#105)
- Create DLT_LOOP Plugin (#106)
- Properly decode ethernet frames when they are VLAN tagged (#84)
- Do not install man2html (#85)
- Add configure --disable-libopts-install option (#86)
- Enhance tcpreplay --oneatatime (#90)
- libtcpedit can now return warnings & errors (#92)
- Fix tcpprep --include/exclude (#96)
- Upgrade AutoGen tearoff (libopts) to latest version (5.9.0) (#97)
- Don't do L4 checksums for non-fragment offset == 0 (#107)
08/07/2006: Version 3.0.beta11
- Fix distribution to ship missing src/tcpr.h (#73)
- Add support to tcprewrite to alter output file DLT (#74)
- Fix errors in 'make test' (little endian still broken) (#77)
- Tweak Autogen .def files documentation (#78)
08/05/2006: Version 3.0.beta10
- tcpprep & tcprewrite no longer require root access (#3)
- Develop wrapper API for libnet, libpcap, BPF and PF_PACKET (#4, #24)
- Enhance do_sleep() to support looping for better accuracy (#6)
- Prefer inet_pton over older, deprecated routines (#26)
- Remove libnet as a requirement (#29)
- Optionally don't rewrite broadcast/multicast IP/MAC addresses (#38)
- Remove libnids dependancy for flowreplay (#55)
- Fix build issues when libpcapnav is installed (#56)
- Fix truncate feature not putting correct packet length in IP header (#59)
- Internal error reporting fixes in libtcpedit (#60)
- Support --enable-debug when building under gcc 3.x (#62)
- tcpedit_stub.h wasn't being generated automatically from SVN (#63)
- Fix 'make doxygen' (#67)
- Fix some Makefile issues (#68)
- tcprewrite --endpoints should require a cache file (#70)
- Improve IP randomizer code to be more random (#71)
07/17/2006: Version 3.0.beta9
- Fix compile issue for users not having AutoOpts installed (#54)
- Fix compile issue for users w/ AutoOpts 5.8.4 (upgrade to 5.8.4)
07/16/2006: Version 3.0.beta8
- Fix -M running in MBps rather then Mbps
- Fix tcpbridge segfault/bus error reported by Steven Z. (Gerry)
- Improve tcpbridge man page
- Massive tcprewrite fixes & cleanup (#50)
- Much improved README document
- Reorganize packet editing code into a standalone module (tcpedit)
which has been librarized. (#5)
- Strict code cleanup (#27)
- Fix tcpprep from generating bad cache files (#48)
- Add MAC split mode for tcpprep (#1)
- Improve dbg() to list file/line (#32)
- Add tcpprep statistical reports (#2)
- Reorganize flowreplay code (#46)
- Fix conflicting speed_t for Debian (#33)
- Too many other things to document
08/07/2005: Version 3.0.beta7
- New 'make doxygen' target builds pretty source code docs in
docs/web/doxygen/html
- Fix tcpprep auto/router mode which was sending all packets out the
secondary interface
- Fix endian issue on little-endian systems which made tcpprep think all
packets were not IP
- Improve debugability of tcpprep
- Fix UDP header offset bug in flowreplay
06/28/2005: Version 3.0.beta6
- Fix rpm .spec file which was still based on tcpreplay 2.x (untested)
- Detect and manually include pcap-bpf.h which fixes compile problem
- Fix tcprewrite -S crash with only one MAC
- Fix tcpreplay using 2nd NIC split mode
- Fix tcpreplay packet counter initialization
- Fix tcpprep to properly handle missing -i and -c with -I and -P
06/14/2005: Version 3.0.beta5
- Fix --decode flag
- Fix compile under AMD64/RHEL4 where libraries are in /usr/lib64
- tarball now ships with a full test subdir
- Fix compile of src/common/get.c under strictly aligned architectures
- Fix ./configure --enable-64bits flag
- Fix bug on little endian systems which prevented tcprewrite from
editing packets
- Fix tcprewrite linktype checks
- Add --pktlen for when the pcap snaplen lies to us
- Add --enable-dynamic-link for those who want to dynamically link their
libs
06/05/2005: Version 3.0.beta4
- Really fix compile problems with dlt2desc with old versions of libpcap
- All libraries are now statically linked and full-path #includes. This
should fix problems with people who have different versions of
libraries installed in different locations.
- Fix problems compiling on systems with libpcapnav
- Add support for libpcap 0.5 such as on OpenBSD
- Fix tcpprep --verbose
- Close STDIN prior to re-opening it for certain OS's
05/04/2005: Version 3.0.beta3
- Fix autoconf problems with --with-libnet
- Fix compile problems with dlt2desc with old versions of libpcap
- Fix compile problem due to not shipping flowreplay_opts.h and
tcpbridge_opts.h
04/19/2005: Version 3.0.beta2
- Significant improvements to FAQ and manual
- Use autoopts for flowreplay
- Be more cautious about memcpy's
- Fix numerous warnings during compile
- Allow overriding L2 protocol field for DLT_RAW
- tcpprep -I & -P now take the cache filename
- Lots of cleanup
- Added tcpbridge utility
- Fix tcpreplay --mbps which was being interpreted as bps
- Add --no-arg-comment feature for tcpprep
- Improve auto-tests and fix old broken ones
- Fix Makefile errors in the docs directory
- Upgrade libopts tear off to v5.7pre12 which fixes problems with
loading config files
- Add support for forcing the use of the local libopts tearoff code
02/27/2005: Version 3.0.beta1
- Major code cleanups and rewriting
- Rip out all edit functions from tcpreplay and put into tcprewrite
- Improve tcpreplay performance by about 5% for raw sending
- Move around utility functions for greater code-reuse
- Move MAC Address funcs into mac.c
- Move global defines into defines.h
- Standardize use of structs and typedefs
- Start passing const's when we don't need to modify
- Start using GNU AutoOpts for arg/config file processing
- Start using automake and autoheader
- Major rewrite of configure.in
- Add support for printing which interface packets go out
- 64bit counters are optional via --enable-64bits
- Can now rewrite L2 data per outbound interface
- Add support for additional DLT types
- Non-Code changes
- I now own the full copyright for tcpreplay
- Removed the evil 4th clause from the BSD license
- Start updating the FAQ and split some content to make a manual
- Automatically generate man pages based via autogen
- New Applications:
- tcprewrite
- Removed Applications: (Ethereal has better utilities)
- capinfo
- pcapmerge
- Merge fixes from 2.x/stable branch:
- portmap.c endian bugs
- edit_packet.c handle corrupted pcap's where caplen < len
- configure now properly uses --with-libnet and --with-libpcap
*** Fork 3.x Branch from v2.3.1 ***

59
docs/CREDIT Normal file
View File

@@ -0,0 +1,59 @@
$Id: CREDIT 2308 2009-05-06 19:05:38Z aturner $
tcpreplay and it's associated utilities (tcpprep, tcprewrite and flowreplay)
were designed and written by Aaron Turner.
This product includes software developed by the University of California,
Berkeley, Lawrence Berkeley Laboratory and its contributors.
The following is a list of people in no particular order who have kindly
submitted patches or code snippets for me to use in tcpreplay.
Matt Bing <matt@mutedwarf.com>
- Matt helped write a lot of the 1.x code
Branden Moore <bmoore-at-cse.nd.edu>
- Patch to pad truncated packets
- Patch to allow specifying a destination MAC w/ only a single NIC
Scott Mace <smace@intt.org>
- Patch for tcpreplay to support CIDR mode
- Patch for ignoring martian IP packets
Jeffrey Guttenfelder <guttenfelder@sourceforge.net>
- Code for pausing/restarting tcpreplay via signals.
John Carlson
- Patch for improved timerdiv() accuracy
Frey Kuo <kero@3sheep.com>
- Patch to replace pause option with packets/sec
Seth Robertson (seth at sysd dot com)
- Patch to allow replaying of live traffic
Nick Mathewson <nickm@freehaven.net>
- Kindly giving me his BSD licensed implimentation of poll()
using select() so I don't have to worry about cross platform
issues.
Denis McLaughlin <denism@cyberus.ca>
- Patch to allow TCP/UDP port translation
Andrew Edgecombe <andrew.edgecombe@nec.com.au>
- Patch to support caching pcap files in memory when looping
which provides a significant performance improvement
- Patch to fix issue with -M option
Joerg Mayer <jmayer@loplof.de>
- Patch for auto* to fix various warnings & errors
Jim West <jim_west@agilent.com>
- Patch to fix Solaris compiling issues
Bojan Smojver <bojan@rexursive.com>
- For maintaining the RPM package and helping with portability issues
Stas Grabois <sagig@radware.com>
- For his efforts to add IPv6 support to tcpprep and the tcpedit engine
- For adding IPv6 support to fragroute

61
docs/HACKING Normal file
View File

@@ -0,0 +1,61 @@
$Id: HACKING 1782 2007-04-02 04:21:30Z aturner $
Guide to Hacking Tcpreplay
[Note: Pay attention to the last update date at the top of this file. If it
was significantly long ago, this document may be out of date.]
0. Contributing Code
If you contribute code the following will happen:
a) You will be given credit in the CREDITS file
b) Your code will be licensed under the same license as that of tcpreplay
c) You will be assigning your copyright to me- Aaron Turner
If you have any questions regarding any of the three above stipulations,
feel free to email the list at: tcpreplay-users@lists.sourceforge.net
1. Introduction
If you're reading this to find out how to add a new feature or fix a bug in
tcpreplay or tcpprep, then you've come to the right place. This isn't the
place to find answers regarding how to use tcpreplay, the meaning of life,
etc.
2. File Layout
The file layout is pretty simple:
/ - Base directory
/lib - 3rd party libraries stolen verbatim
/libopts - GNU AutoOpts tearoff
/src - Main code routines
/src/common - Common routines for all binaries
/src/tcpedit - libtcpedit
/docs - Where to find documentation
/test - Test scripts and stuff which is used during 'make test'
3. Coding Standards
1) Indent 4 spaces using spaces, not tabs
2) Opening braces for control blocks (if, while, etc) should be on the same line
3) Opening braces for functions should be on next line
4) Use provided warnx, dbg, and errx functions provided in err.h
5) Use provided safe_strdup, safe_malloc and safe_realloc functions provided
in common/utils.h
6) Use provided strl* functions in lib/strlcat.c and lib/strlcpy.c
4. Adding support for additional DLTs (Data Link Types)
libtcpedit supports a plugin based architecture for handling different DLT
types. If you wish to add support for another DLT type, you should read:
http://tcpreplay.synfin.net/trac/wiki/tcpeditDeveloper
Which contains information on creating new DLT plugins.
5. Hacking tcprewrite
Tcprewrite is basically a front-end to libtcpedit. Hence any packet editing
improvements should be done there. However, please remember that tcprewrite
is not the only application which uses libtcpedit (tcpbridge is another
example) so make sure you test your code there too.

6
docs/INSTALL Normal file
View File

@@ -0,0 +1,6 @@
$Id: INSTALL 1762 2007-03-24 20:42:05Z aturner $
NOTE: This information is out of date. Please see the tcpreplay wiki
for updated information:
http://tcpreplay.synfin.net/trac/wiki/manual#GettingTcpreplayInstalled

31
docs/LICENSE Normal file
View File

@@ -0,0 +1,31 @@
$Id: LICENSE 2441 2010-03-30 03:21:52Z aturner $
Copyright (c) 2001-2010 Aaron Turner. aturner at synfin dot net
All rights reserved.
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 names of the copyright owners nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``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 AUTHORS OR COPYRIGHT HOLDERS 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.
This product includes software developed by the University of California,
Berkeley, Lawrence Berkeley Laboratory and its contributors.

41
docs/Makefile.am Normal file
View File

@@ -0,0 +1,41 @@
MAKEFLAGS=-s
.PHONY: manpages
docs: clean-docs manpages
web/tcpreplay.html:
@GROFF@ -Thtml -mman ../src/tcpreplay.1 > web/tcpreplay.html
web/tcpprep.html:
@GROFF@ -Thtml -mman ../src/tcpprep.1 > web/tcpprep.html
web/tcprewrite.html:
@GROFF@ -Thtml -mman ../src/tcprewrite.1 > web/tcprewrite.html
web/tcpbridge.html:
@GROFF@ -Thtml -mman ../src/tcpbridge.1 > web/tcpbridge.html
web/tcpreplay-edit.html:
@GROFF@ -Thtml -mman ../src/tcpreplay-edit.1 > web/tcpreplay-edit.html
manpages: web/tcpreplay.html web/tcpprep.html web/tcprewrite.html \
web/tcpbridge.html web/tcpreplay-edit.html
postweb: manpages
rsync -qe ssh --exclude '.svn/' --exclude '/**/.svn/' --exclude '/**~' \
--exclude '*~' -avz web/ \
aturner@malbec.synfin.net:/var/vhosts/tcpreplay/
scp CHANGELOG TODO aturner@malbec.synfin.net:/var/vhosts/tcpreplay/
EXTRA_DIST = CHANGELOG CREDIT HACKING INSTALL LICENSE Win32Readme.txt
clean-docs: clean
-rm -f web/*.html
maintainer-clean-local: clean-docs
-rm -f web/*.html
MAINTAINERCLEANFILES = Makefile.in

422
docs/Makefile.in Normal file
View File

@@ -0,0 +1,422 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = docs
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in INSTALL TODO
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAKEFLAGS = -s
EXTRA_DIST = CHANGELOG CREDIT HACKING INSTALL LICENSE Win32Readme.txt
MAINTAINERCLEANFILES = Makefile.in
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu docs/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic \
maintainer-clean-local
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic maintainer-clean-local mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
uninstall uninstall-am
.PHONY: manpages
docs: clean-docs manpages
web/tcpreplay.html:
@GROFF@ -Thtml -mman ../src/tcpreplay.1 > web/tcpreplay.html
web/tcpprep.html:
@GROFF@ -Thtml -mman ../src/tcpprep.1 > web/tcpprep.html
web/tcprewrite.html:
@GROFF@ -Thtml -mman ../src/tcprewrite.1 > web/tcprewrite.html
web/tcpbridge.html:
@GROFF@ -Thtml -mman ../src/tcpbridge.1 > web/tcpbridge.html
web/tcpreplay-edit.html:
@GROFF@ -Thtml -mman ../src/tcpreplay-edit.1 > web/tcpreplay-edit.html
manpages: web/tcpreplay.html web/tcpprep.html web/tcprewrite.html \
web/tcpbridge.html web/tcpreplay-edit.html
postweb: manpages
rsync -qe ssh --exclude '.svn/' --exclude '/**/.svn/' --exclude '/**~' \
--exclude '*~' -avz web/ \
aturner@malbec.synfin.net:/var/vhosts/tcpreplay/
scp CHANGELOG TODO aturner@malbec.synfin.net:/var/vhosts/tcpreplay/
clean-docs: clean
-rm -f web/*.html
maintainer-clean-local: clean-docs
-rm -f web/*.html
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

151
docs/TODO Normal file
View File

@@ -0,0 +1,151 @@
This is a general list of things which should/could/may be done.
If any of these features interest you let me know- especially if you're
willing and able to help code it. In general, higher priority tasks are
tracked on the tcpreplay website: http://tcpreplay.synfin.net/
Legend:
- = Not started
+ = Done
O = Mostly done
o = Started work
. = Canceled
? = To think about
GENERAL:
+ Improve config file format
+ better variable names
+ use "var: value" format
+ have tcpreplay, tcpprep, tcprewrite sections
+ Being solved using GNU AutoOpts
+ Improve autoconf detection of libraries
+ Re-organize source tree
+ tcpdump decoder should print packets syncronously w/ the main process
+ Better use of GNU Autotools
+ Improve CLI/config file parsing
+ Only tcpreplay/tcpbridge should need to run as root.
+ Tcpreplay should use raw sockets or BPF directly for writing rather then
libnet where applicable for theoretically higher performance.
- Detect system version of libopts b/c we need a recent version
+ Generalize packet editing and printing code so it can be shipped as a
seperate library and plugged into tcpreplay/tcprewrite/flowreplay/etc
+ See about removing libnet_init() from all binaries other then tcprewrite
so we don't have to run as root:
. libnet_addr2name4 (ignore, doesn't require libnet_t context)
+ libnet_name2addr4
+ libnet_get_hwaddr
+ libnet_do_checksum
TCPREPLAY:
. Add support for dual-nic send on one intf, wait for packet, send next.
would be really useful for testing the effectiveness of how well an IPS
detects and blocks attacks. (TP's tomahawk does this even better then
described here, so why re-invent the wheel?)
- Rewrite do_sleep() to handle sub sleep times by only nanosleep()'ing
once for multiple packets when the timestamps are close enough. We
also need to time nanosleep, since different architectures have lower
minimum sleep times (Linux/Alpha is 1ms vs. 10ms for Linux/x86)
+ Tcpreplay should say which interface each packet is going out
TCPBRIDGE:
- Duplicate all tcprewrite functionality
TCPREWRITE:
- Support fragrouter like features
- basic IP fragmenation
- TCP fudging
- then more advanced stuff
- Can we integrate FR's code?
+ Look at VLAN (802.1q) packets
- others non-vanilla types?
+ Add tags? Remove tags? Change tags?
- Tag only one side of the connection
- Support Q-in-Q tags:
http://www.informit.com/articles/article.asp?p=101367&rl=1
- Cisco's ISL trunking?
- Add support for MPLS
- Add support for GRE
http://www.linuxguruz.com/iptables/howto/2.4routing-5.html
Perhaps this should be done via the hardware interface rather then the GRE
virtual interface since libnet doesn't support the GRE virtual
+ Add support for setting the ethernet protocol field so we can use
-I, -K to fill out an entire ethernet header w/o using -2
+ Add a secondary interface full layer two rewrite option
+ Fix MAC rewriting to allow sending packets with a MAC of 00:00:00:00:00:00
- Add support for more linktypes (Prism Monitor, 802.11, FDDI, etc)
+ Make it easier for others to add support for others
+ Rip out packet munger from tcpreplay and put it into another tool so
that tcpreplay can be more optimized
? perhaps use libnetdude?
? make into a library?
+ definately put it into a seperate binary (tcprewrite)
- Add the ability to modify packet data via regex(es) in tcprewrite
- Should support pcre
- Support (foo) and $1, etc so new data can include old
- Limit matching which packets via BPF filter and tcpprep cache
(client/server)
- Step through packets ala tcpreplay and provide option to edit (Y/n)
- Support connection tracking and generating 3way handshake for connections
missing them.
- Bump Syn/Ack numbers by a pseudo random or given value so that running
the same pcap will behave as different streams.
- IPv6 support? People ask for this every few months, but nobody actually
says they "need" or "really want" it; seems more of "gee, wouldn't it be
nice". What does that mean anyways???
- tcprewrite should be able to remove the two byte ethernet FCS (checksums)
at the end of the frame.
+ Support randomization of IP addresses in ARP packets
- Add support for rewriting MAC addresses in the ARP body for
tcprewrite/tcpbridge to allow proxy-arp like behaviour
- Add support for IP fragmenting frames which are > MTU
TCPPREP:
+ When splitting traffic via tcpprep print out each packet (tcpdump style)
so end users know where each packet is going
FLOWREPLAY:
- Improve flowreplay so it actually works
. Use libnids to read the pcaps. This seems DOA at this time since
libnids is GPL and the author is unwilling to make it support multiple
threads which flowreplay probably needs to be. The only other option is
a major rewrite which would break API compatibility. Doesn't seem worth
it.
- Allow handoff to a socket after user specified client/server exchanges
- Perhaps integrate stick/snot/fpg logic into flowreplay:
http://www.geschke-online.de/FLoP/fpg.8.html
to do full 3way handshakes

106
docs/Win32Readme.txt Normal file
View File

@@ -0,0 +1,106 @@
$Id: Win32Readme.txt 2102 2009-01-04 22:52:51Z aturner $
This document attempts to explain how to get tcpreplay compiled and running
under Windows. Please note that this document is a work in progress and
Windows support in general considered EXPERIMENTAL right now.
Background:
Tcpreplay is not a native Win32 application right now. Hence it requires
Cygwin. (http://www.cygwin.com). Cygwin creates a Linux-like environment
on your Windows system which allows Linux/UNIX programs to run after a
recompile.
Tcpreplay supports numerous API's for sending packets depending on the
operating system. Under Windows, the only supported method of sending
packets is with WinPcap 4.0. (http://www.winpcap.org) Please be sure to
install both the WinPcap driver AND the developer pack.
Right now, I've only done testing under Windows XP. My guess is that 2000
and 2003 should have no problems. Since WinPcap and Cygwin are EOL'ing
support for Win98/ME, I doubt that they'll ever be supported. Not sure
the story on Vista, but I assume WinPcap & Cygwin will support them sooner
or later if not already. Would love to hear if anyone has any luck one
way or another.
What you will need:
- Cygwin environment
- GCC compiler and system header files
- WinPcap 4.0 DLL
- WinPcap 4.0 Developer Pack aka WpdPack (headers, etc)
Additional requirements if building from SVN:
- GNU build chain tools (Autoconf, Automake, Autoheader)
- GNU Autogen (*)
* NOTE: The guile package which comes with Cygwin is broken and breaks
Autogen, so you'll need to compile guile from scratch to fix. Hence, I
strongly suggest you build Tcpreplay from the tarball and not SVN. See
below for how to "fix" this issue if you want to compile from SVN.
******************************* IMPORTANT ******************************
Note 1:
People have reported problems with WpdPack (the developer pack for
Winpcap) being installed outside of the Cygwin root directory. Hence, I
strongly recommend you install it under the Cygwin root as /WpdPack.
Note 2:
There's a big problem with the Cygwin Guile package which breaks
GNU Autogen which Tcpreplay depends on when building from Subversion.
What this means is that to build from Subversion you must do the following:
- Download GNU Guile from http://www.gnu.org/software/guile/guile.html
- Extract the tarball and do the following:
libtoolize --copy --force
./configure
make
make install
This will install guile in /usr/local.
The other problem is that guile-config returns the linker flags in the wrong
order. To fix this, rename /usr/local/bin/guile-config to
/usr/local/bin/guile-config.original and create a new shell script in it's
place:
---- BEGIN SHELL SCRIPT ----
#!/bin/bash
# Replacement /usr/local/bin/guile-config script
if test -z "$1" ; then
guile-config.original
elif test "$1" == "link"; then
echo "-L/usr/local/lib -lguile -lltdl -lgmp -lcrypt -lm -lltdl"
else
guile-config.original $1
fi
---- END SHELL SCRIPT ----
******************************* IMPORTANT ******************************
Directions:
- Install all the requirements
- Enter into the Cygwin environment by clicking on the Cygwin icon
- If you checked out the code from SVN, see Note 2 above and then run
the autogen.sh bootstrapper:
./autogen.sh
- Configure tcpreplay:
./configure --enable-debug
- Build tcpreplay:
make
- Install:
make install
- Try it out!

1230
doxygen.cfg.in Normal file

File diff suppressed because it is too large Load Diff

9
lib/Makefile.am Normal file
View File

@@ -0,0 +1,9 @@
noinst_LIBRARIES = libstrl.a
libstrl_a_SOURCES = strlcat.c strlcpy.c
noinst_HEADERS = strlcpy.h tree.h queue.h sll.h
MOSTLYCLEANFILES = *~ *.o *.a
MAINTAINERCLEANFILES = Makefile.in

505
lib/Makefile.in Normal file
View File

@@ -0,0 +1,505 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = lib
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LIBRARIES = $(noinst_LIBRARIES)
ARFLAGS = cru
libstrl_a_AR = $(AR) $(ARFLAGS)
libstrl_a_LIBADD =
am_libstrl_a_OBJECTS = strlcat.$(OBJEXT) strlcpy.$(OBJEXT)
libstrl_a_OBJECTS = $(am_libstrl_a_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libstrl_a_SOURCES)
DIST_SOURCES = $(libstrl_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LIBRARIES = libstrl.a
libstrl_a_SOURCES = strlcat.c strlcpy.c
noinst_HEADERS = strlcpy.h tree.h queue.h sll.h
MOSTLYCLEANFILES = *~ *.o *.a
MAINTAINERCLEANFILES = Makefile.in
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libstrl.a: $(libstrl_a_OBJECTS) $(libstrl_a_DEPENDENCIES)
-rm -f libstrl.a
$(libstrl_a_AR) libstrl.a $(libstrl_a_OBJECTS) $(libstrl_a_LIBADD)
$(RANLIB) libstrl.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcpy.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

503
lib/queue.h Normal file
View File

@@ -0,0 +1,503 @@
/* $OpenBSD: queue.h,v 1.22 2001/06/23 04:39:35 angelos Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR 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.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
*/
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List access methods.
*/
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_END(head) NULL
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_FOREACH(var, head, field) \
for((var) = SLIST_FIRST(head); \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) { \
SLIST_FIRST(head) = SLIST_END(head); \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = (head)->slh_first; \
while( curelm->field.sle_next != (elm) ) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
} while (0)
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List access methods
*/
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_END(head) NULL
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_FOREACH(var, head, field) \
for((var) = LIST_FIRST(head); \
(var)!= LIST_END(head); \
(var) = LIST_NEXT(var, field))
/*
* List functions.
*/
#define LIST_INIT(head) do { \
LIST_FIRST(head) = LIST_END(head); \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
} while (0)
#define LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
} while (0)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
/*
* Simple queue access methods.
*/
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_END(head) NULL
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
#define SIMPLEQ_FOREACH(var, head, field) \
for((var) = SIMPLEQ_FIRST(head); \
(var) != SIMPLEQ_END(head); \
(var) = SIMPLEQ_NEXT(var, field))
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \
if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
/*
* Tail queue definitions.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
*/
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_END(head) NULL
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_EMPTY(head) \
(TAILQ_FIRST(head) == TAILQ_END(head))
#define TAILQ_FOREACH(var, head, field) \
for((var) = TAILQ_FIRST(head); \
(var) != TAILQ_END(head); \
(var) = TAILQ_NEXT(var, field))
#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \
for((var) = TAILQ_LAST(head, headname); \
(var) != TAILQ_END(head); \
(var) = TAILQ_PREV(var, headname, field))
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (0)
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
} while (0)
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
}
/*
* Circular queue access methods
*/
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_END(head) ((void *)(head))
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_EMPTY(head) \
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
#define CIRCLEQ_FOREACH(var, head, field) \
for((var) = CIRCLEQ_FIRST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_NEXT(var, field))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for((var) = CIRCLEQ_LAST(head); \
(var) != CIRCLEQ_END(head); \
(var) = CIRCLEQ_PREV(var, field))
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = CIRCLEQ_END(head); \
(head)->cqh_last = CIRCLEQ_END(head); \
} while (0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
if ((head)->cqh_last == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = CIRCLEQ_END(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
} while (0)
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
CIRCLEQ_END(head)) \
(head).cqh_last = (elm2); \
else \
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
CIRCLEQ_END(head)) \
(head).cqh_first = (elm2); \
else \
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
} while (0)
#endif /* !_SYS_QUEUE_H_ */

139
lib/sll.h Normal file
View File

@@ -0,0 +1,139 @@
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR 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.
*
* @(#) $Header: /home/cvs/tcpreplay/sll.h,v 1.2 2003/12/16 03:58:37 aturner Exp $ (LBL)
*/
/*
* For captures on Linux cooked sockets, we construct a fake header
* that includes:
*
* a 2-byte "packet type" which is one of:
*
* LINUX_SLL_HOST packet was sent to us
* LINUX_SLL_BROADCAST packet was broadcast
* LINUX_SLL_MULTICAST packet was multicast
* LINUX_SLL_OTHERHOST packet was sent to somebody else
* LINUX_SLL_OUTGOING packet was sent *by* us;
*
* a 2-byte Ethernet protocol field;
*
* a 2-byte link-layer type;
*
* a 2-byte link-layer address length;
*
* an 8-byte source link-layer address, whose actual length is
* specified by the previous value.
*
* All fields except for the link-layer address are in network byte order.
*
* DO NOT change the layout of this structure, or change any of the
* LINUX_SLL_ values below. If you must change the link-layer header
* for a "cooked" Linux capture, introduce a new DLT_ type (ask
* "tcpdump-workers@tcpdump.org" for one, so that you don't give it a
* value that collides with a value already being used), and use the
* new header in captures of that type, so that programs that can
* handle DLT_LINUX_SLL captures will continue to handle them correctly
* without any change, and so that capture files with different headers
* can be told apart and programs that read them can dissect the
* packets in them.
*/
#ifndef _SLL_H_
#define _SLL_H_
/*
* A DLT_LINUX_SLL fake link-layer header.
*/
#define SLL_HDR_LEN 16 /* total header length */
#define SLL_ADDRLEN 8 /* length of address field */
struct sll_header {
u_int16_t sll_pkttype; /* packet type */
u_int16_t sll_hatype; /* link-layer address type */
u_int16_t sll_halen; /* link-layer address length */
u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
u_int16_t sll_protocol; /* protocol */
};
/*
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
* PACKET_ values on Linux, but are defined here so that they're
* available even on systems other than Linux, and so that they
* don't change even if the PACKET_ values change.
*/
#define LINUX_SLL_HOST 0
#define LINUX_SLL_BROADCAST 1
#define LINUX_SLL_MULTICAST 2
#define LINUX_SLL_OTHERHOST 3
#define LINUX_SLL_OUTGOING 4
/*
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
* ETH_P_ values on Linux, but are defined here so that they're
* available even on systems other than Linux. We assume, for now,
* that the ETH_P_ values won't change in Linux; if they do, then:
*
* if we don't translate them in "pcap-linux.c", capture files
* won't necessarily be readable if captured on a system that
* defines ETH_P_ values that don't match these values;
*
* if we do translate them in "pcap-linux.c", that makes life
* unpleasant for the BPF code generator, as the values you test
* for in the kernel aren't the values that you test for when
* reading a capture file, so the fixup code run on BPF programs
* handed to the kernel ends up having to do more work.
*
* Add other values here as necessary, for handling packet types that
* might show up on non-Ethernet, non-802.x networks. (Not all the ones
* in the Linux "if_ether.h" will, I suspect, actually show up in
* captures.)
*/
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
#endif
/*
Local Variables:
mode:c
indent-tabs-mode:nil
c-basic-offset:4
End:
*/

59
lib/strlcat.c Normal file
View File

@@ -0,0 +1,59 @@
/* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

55
lib/strlcpy.c Normal file
View File

@@ -0,0 +1,55 @@
/* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char *rcsid = "$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
register char *d = dst;
register const char *s = src;
register size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}

12
lib/strlcpy.h Normal file
View File

@@ -0,0 +1,12 @@
#ifndef _STRLCPY_H_
#define _STRLCPY_H_
#include <sys/types.h>
size_t
strlcpy(char *dst, const char *src, size_t size);
size_t
strlcat(char *dst, const char *src, size_t size);
#endif

675
lib/tree.h Normal file
View File

@@ -0,0 +1,675 @@
/* $OpenBSD: tree.h,v 1.6 2002/06/11 22:09:52 provos Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
*
* 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.
*
* 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.
*/
#ifndef _SYS_TREE_H_
#define _SYS_TREE_H_
/*
* This file defines data structures for different types of trees:
* splay trees and red-black trees.
*
* A splay tree is a self-organizing data structure. Every operation
* on the tree causes a splay to happen. The splay moves the requested
* node to the root of the tree and partly rebalances it.
*
* This has the benefit that request locality causes faster lookups as
* the requested nodes move to the top of the tree. On the other hand,
* every lookup causes memory writes.
*
* The Balance Theorem bounds the total access time for m operations
* and n inserts on an initially empty tree as O((m + n)lg n). The
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
*
* A red-black tree is a binary search tree with the node color as an
* extra attribute. It fulfills a set of conditions:
* - every search path from the root to a leaf consists of the
* same number of black nodes,
* - each red node (except for the root) has a black parent,
* - each leaf node is black.
*
* Every operation on a red-black tree is bounded as O(lg n).
* The maximum height of a red-black tree is 2lg (n+1).
*/
#define SPLAY_HEAD(name, type) \
struct name { \
struct type *sph_root; /* root of the tree */ \
}
#define SPLAY_INITIALIZER(root) \
{ NULL }
#define SPLAY_INIT(root) do { \
(root)->sph_root = NULL; \
} while (0)
#define SPLAY_ENTRY(type) \
struct { \
struct type *spe_left; /* left element */ \
struct type *spe_right; /* right element */ \
}
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
#define SPLAY_ROOT(head) (head)->sph_root
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_LINKLEFT(head, tmp, field) do { \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
} while (0)
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
} while (0)
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
} while (0)
/* Generates prototypes and inline functions */
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
void name##_SPLAY(struct name *, struct type *); \
void name##_SPLAY_MINMAX(struct name *, int); \
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
\
/* Finds the node with the same key as elm */ \
static __inline struct type * \
name##_SPLAY_FIND(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) \
return(NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) \
return (head->sph_root); \
return (NULL); \
} \
\
static __inline struct type * \
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
{ \
name##_SPLAY(head, elm); \
if (SPLAY_RIGHT(elm, field) != NULL) { \
elm = SPLAY_RIGHT(elm, field); \
while (SPLAY_LEFT(elm, field) != NULL) { \
elm = SPLAY_LEFT(elm, field); \
} \
} else \
elm = NULL; \
return (elm); \
} \
\
static __inline struct type * \
name##_SPLAY_MIN_MAX(struct name *head, int val) \
{ \
name##_SPLAY_MINMAX(head, val); \
return (SPLAY_ROOT(head)); \
}
/* Main splay operation.
* Moves node close to the key of elm to top
*/
#define SPLAY_GENERATE(name, type, field, cmp) \
struct type * \
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if(__comp < 0) { \
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return ((head)->sph_root); \
} \
(head)->sph_root = (elm); \
return (NULL); \
} \
\
struct type * \
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
return (elm); \
} \
return (NULL); \
} \
\
void \
name##_SPLAY(struct name *head, struct type *elm) \
{ \
struct type __node, *__left, *__right, *__tmp; \
int __comp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
__left = __right = &__node; \
\
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) > 0){ \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
} \
\
/* Splay with either the minimum or the maximum element \
* Used to find minimum or maximum element in tree. \
*/ \
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
{ \
struct type __node, *__left, *__right, *__tmp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
__left = __right = &__node; \
\
while (1) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp > 0) { \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
}
#define SPLAY_NEGINF -1
#define SPLAY_INF 1
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
#define SPLAY_FOREACH(x, name, head) \
for ((x) = SPLAY_MIN(name, head); \
(x) != NULL; \
(x) = SPLAY_NEXT(name, head, x))
/* Macros that define a red-back tree */
#define RB_HEAD(name, type) \
struct name { \
struct type *rbh_root; /* root of the tree */ \
}
#define RB_INITIALIZER(root) \
{ NULL }
#define RB_INIT(root) do { \
(root)->rbh_root = NULL; \
} while (0)
#define RB_BLACK 0
#define RB_RED 1
#define RB_ENTRY(type) \
struct { \
struct type *rbe_left; /* left element */ \
struct type *rbe_right; /* right element */ \
struct type *rbe_parent; /* parent element */ \
int rbe_color; /* node color */ \
}
#define RB_LEFT(elm, field) (elm)->field.rbe_left
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
#define RB_COLOR(elm, field) (elm)->field.rbe_color
#define RB_ROOT(head) (head)->rbh_root
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
#define RB_SET(elm, parent, field) do { \
RB_PARENT(elm, field) = parent; \
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
RB_COLOR(elm, field) = RB_RED; \
} while (0)
#define RB_SET_BLACKRED(black, red, field) do { \
RB_COLOR(black, field) = RB_BLACK; \
RB_COLOR(red, field) = RB_RED; \
} while (0)
#ifndef RB_AUGMENT
#define RB_AUGMENT(x)
#endif
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
(tmp) = RB_RIGHT(elm, field); \
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
} \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
RB_AUGMENT(RB_PARENT(elm, field)); \
} else \
(head)->rbh_root = (tmp); \
RB_LEFT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \
} while (0)
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
(tmp) = RB_LEFT(elm, field); \
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
} \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
RB_AUGMENT(RB_PARENT(elm, field)); \
} else \
(head)->rbh_root = (tmp); \
RB_RIGHT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \
} while (0)
/* Generates prototypes and inline functions */
#define RB_PROTOTYPE(name, type, field, cmp) \
void name##_RB_INSERT_COLOR(struct name *, struct type *); \
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
struct type *name##_RB_REMOVE(struct name *, struct type *); \
struct type *name##_RB_INSERT(struct name *, struct type *); \
struct type *name##_RB_FIND(struct name *, struct type *); \
struct type *name##_RB_NEXT(struct name *, struct type *); \
struct type *name##_RB_MINMAX(struct name *, int); \
\
/* Main rb operation.
* Moves node close to the key of elm to top
*/
#define RB_GENERATE(name, type, field, cmp) \
void \
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
{ \
struct type *parent, *gparent, *tmp; \
while ((parent = RB_PARENT(elm, field)) && \
RB_COLOR(parent, field) == RB_RED) { \
gparent = RB_PARENT(parent, field); \
if (parent == RB_LEFT(gparent, field)) { \
tmp = RB_RIGHT(gparent, field); \
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
RB_COLOR(tmp, field) = RB_BLACK; \
RB_SET_BLACKRED(parent, gparent, field);\
elm = gparent; \
continue; \
} \
if (RB_RIGHT(parent, field) == elm) { \
RB_ROTATE_LEFT(head, parent, tmp, field);\
tmp = parent; \
parent = elm; \
elm = tmp; \
} \
RB_SET_BLACKRED(parent, gparent, field); \
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
} else { \
tmp = RB_LEFT(gparent, field); \
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
RB_COLOR(tmp, field) = RB_BLACK; \
RB_SET_BLACKRED(parent, gparent, field);\
elm = gparent; \
continue; \
} \
if (RB_LEFT(parent, field) == elm) { \
RB_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = parent; \
parent = elm; \
elm = tmp; \
} \
RB_SET_BLACKRED(parent, gparent, field); \
RB_ROTATE_LEFT(head, gparent, tmp, field); \
} \
} \
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
} \
\
void \
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
{ \
struct type *tmp; \
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
elm != RB_ROOT(head)) { \
if (RB_LEFT(parent, field) == elm) { \
tmp = RB_RIGHT(parent, field); \
if (RB_COLOR(tmp, field) == RB_RED) { \
RB_SET_BLACKRED(tmp, parent, field); \
RB_ROTATE_LEFT(head, parent, tmp, field);\
tmp = RB_RIGHT(parent, field); \
} \
if ((RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
(RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
} else { \
if (RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
struct type *oleft; \
if ((oleft = RB_LEFT(tmp, field)))\
RB_COLOR(oleft, field) = RB_BLACK;\
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_RIGHT(head, tmp, oleft, field);\
tmp = RB_RIGHT(parent, field); \
} \
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
RB_COLOR(parent, field) = RB_BLACK; \
if (RB_RIGHT(tmp, field)) \
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
RB_ROTATE_LEFT(head, parent, tmp, field);\
elm = RB_ROOT(head); \
break; \
} \
} else { \
tmp = RB_LEFT(parent, field); \
if (RB_COLOR(tmp, field) == RB_RED) { \
RB_SET_BLACKRED(tmp, parent, field); \
RB_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = RB_LEFT(parent, field); \
} \
if ((RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
(RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
} else { \
if (RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
struct type *oright; \
if ((oright = RB_RIGHT(tmp, field)))\
RB_COLOR(oright, field) = RB_BLACK;\
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_LEFT(head, tmp, oright, field);\
tmp = RB_LEFT(parent, field); \
} \
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
RB_COLOR(parent, field) = RB_BLACK; \
if (RB_LEFT(tmp, field)) \
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
RB_ROTATE_RIGHT(head, parent, tmp, field);\
elm = RB_ROOT(head); \
break; \
} \
} \
} \
if (elm) \
RB_COLOR(elm, field) = RB_BLACK; \
} \
\
struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *child, *parent, *old = elm; \
int color; \
if (RB_LEFT(elm, field) == NULL) \
child = RB_RIGHT(elm, field); \
else if (RB_RIGHT(elm, field) == NULL) \
child = RB_LEFT(elm, field); \
else { \
struct type *left; \
elm = RB_RIGHT(elm, field); \
while ((left = RB_LEFT(elm, field))) \
elm = left; \
child = RB_RIGHT(elm, field); \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child) \
RB_PARENT(child, field) = parent; \
if (parent) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
if (RB_PARENT(elm, field) == old) \
parent = elm; \
(elm)->field = (old)->field; \
if (RB_PARENT(old, field)) { \
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
RB_LEFT(RB_PARENT(old, field), field) = elm;\
else \
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
RB_AUGMENT(RB_PARENT(old, field)); \
} else \
RB_ROOT(head) = elm; \
RB_PARENT(RB_LEFT(old, field), field) = elm; \
if (RB_RIGHT(old, field)) \
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
if (parent) { \
left = parent; \
do { \
RB_AUGMENT(left); \
} while ((left = RB_PARENT(left, field))); \
} \
goto color; \
} \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child) \
RB_PARENT(child, field) = parent; \
if (parent) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
color: \
if (color == RB_BLACK) \
name##_RB_REMOVE_COLOR(head, parent, child); \
return (old); \
} \
\
/* Inserts a node into the RB tree */ \
struct type * \
name##_RB_INSERT(struct name *head, struct type *elm) \
{ \
struct type *tmp; \
struct type *parent = NULL; \
int comp = 0; \
tmp = RB_ROOT(head); \
while (tmp) { \
parent = tmp; \
comp = (cmp)(elm, parent); \
if (comp < 0) \
tmp = RB_LEFT(tmp, field); \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
RB_SET(elm, parent, field); \
if (parent != NULL) { \
if (comp < 0) \
RB_LEFT(parent, field) = elm; \
else \
RB_RIGHT(parent, field) = elm; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = elm; \
name##_RB_INSERT_COLOR(head, elm); \
return (NULL); \
} \
\
/* Finds the node with the same key as elm */ \
struct type * \
name##_RB_FIND(struct name *head, struct type *elm) \
{ \
struct type *tmp = RB_ROOT(head); \
int comp; \
while (tmp) { \
comp = cmp(elm, tmp); \
if (comp < 0) \
tmp = RB_LEFT(tmp, field); \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
return (NULL); \
} \
\
struct type * \
name##_RB_NEXT(_U_ struct name *head, struct type *elm) \
{ \
if (RB_RIGHT(elm, field)) { \
elm = RB_RIGHT(elm, field); \
while (RB_LEFT(elm, field)) \
elm = RB_LEFT(elm, field); \
} else { \
if (RB_PARENT(elm, field) && \
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
elm = RB_PARENT(elm, field); \
else { \
while (RB_PARENT(elm, field) && \
(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
elm = RB_PARENT(elm, field); \
elm = RB_PARENT(elm, field); \
} \
} \
return (elm); \
} \
\
struct type * \
name##_RB_MINMAX(struct name *head, int val) \
{ \
struct type *tmp = RB_ROOT(head); \
struct type *parent = NULL; \
while (tmp) { \
parent = tmp; \
if (val < 0) \
tmp = RB_LEFT(tmp, field); \
else \
tmp = RB_RIGHT(tmp, field); \
} \
return (parent); \
}
#define RB_NEGINF -1
#define RB_INF 1
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y)
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
#define RB_FOREACH(x, name, head) \
for ((x) = RB_MIN(name, head); \
(x) != NULL; \
(x) = name##_RB_NEXT(head, x))
#endif /* _SYS_TREE_H_ */

674
libopts/COPYING.gplv3 Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
copyright (c) 2009 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
libopts/COPYING.lgplv3 Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
copyright (c) 2009 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
libopts/COPYING.mbsd Normal file
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.

0
libopts/MakeDefs.inc Normal file
View File

28
libopts/Makefile.am Normal file
View File

@@ -0,0 +1,28 @@
## LIBOPTS Makefile
MAINTAINERCLEANFILES = Makefile.in
if INSTALL_LIBOPTS
lib_LTLIBRARIES = libopts.la
else
noinst_LTLIBRARIES = libopts.la
endif
libopts_la_SOURCES = libopts.c
libopts_la_CPPFLAGS = -I$(top_srcdir)
libopts_la_LDFLAGS = -version-info 32:2:7
EXTRA_DIST = \
COPYING.gplv3 COPYING.lgplv3 COPYING.mbsd \
MakeDefs.inc README ag-char-map.h \
autoopts/options.h autoopts/usage-txt.h autoopts.c \
autoopts.h boolean.c compat/compat.h \
compat/pathfind.c compat/snprintf.c compat/strchr.c \
compat/strdup.c compat/windows-config.h configfile.c \
cook.c enumeration.c environment.c \
file.c genshell.c genshell.h \
load.c m4/libopts.m4 m4/liboptschk.m4 \
makeshell.c nested.c numeric.c \
parse-duration.c parse-duration.h pgusage.c \
proto.h putshell.c 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

591
libopts/Makefile.in Normal file
View File

@@ -0,0 +1,591 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = libopts
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)"
LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
libopts_la_LIBADD =
am_libopts_la_OBJECTS = libopts_la-libopts.lo
libopts_la_OBJECTS = $(am_libopts_la_OBJECTS)
libopts_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libopts_la_LDFLAGS) $(LDFLAGS) -o $@
@INSTALL_LIBOPTS_FALSE@am_libopts_la_rpath =
@INSTALL_LIBOPTS_TRUE@am_libopts_la_rpath = -rpath $(libdir)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libopts_la_SOURCES)
DIST_SOURCES = $(libopts_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = Makefile.in
@INSTALL_LIBOPTS_TRUE@lib_LTLIBRARIES = libopts.la
@INSTALL_LIBOPTS_FALSE@noinst_LTLIBRARIES = libopts.la
libopts_la_SOURCES = libopts.c
libopts_la_CPPFLAGS = -I$(top_srcdir)
libopts_la_LDFLAGS = -version-info 32:2:7
EXTRA_DIST = \
COPYING.gplv3 COPYING.lgplv3 COPYING.mbsd \
MakeDefs.inc README ag-char-map.h \
autoopts/options.h autoopts/usage-txt.h autoopts.c \
autoopts.h boolean.c compat/compat.h \
compat/pathfind.c compat/snprintf.c compat/strchr.c \
compat/strdup.c compat/windows-config.h configfile.c \
cook.c enumeration.c environment.c \
file.c genshell.c genshell.h \
load.c m4/libopts.m4 m4/liboptschk.m4 \
makeshell.c nested.c numeric.c \
parse-duration.c parse-duration.h pgusage.c \
proto.h putshell.c 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
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu libopts/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu libopts/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libopts.la: $(libopts_la_OBJECTS) $(libopts_la_DEPENDENCIES)
$(libopts_la_LINK) $(am_libopts_la_rpath) $(libopts_la_OBJECTS) $(libopts_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libopts_la-libopts.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libopts_la-libopts.lo: libopts.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopts_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libopts_la-libopts.lo -MD -MP -MF $(DEPDIR)/libopts_la-libopts.Tpo -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libopts_la-libopts.Tpo $(DEPDIR)/libopts_la-libopts.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libopts.c' object='libopts_la-libopts.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libopts_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstLTLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \
ctags distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libLTLIBRARIES install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

93
libopts/README Normal file
View File

@@ -0,0 +1,93 @@
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 the following to your ``configure.ac'' file:
LIBOPTS_CHECK
or:
LIBOPTS_CHECK([relative/path/to/libopts])
This macro will automatically invoke
AC_CONFIG_FILES( [relative/path/to/libopts/Makefile] )
The default ``relative/path/to/libopts'' is simply
``libopts''.
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 -Tagman1.tpl -bprog prog-opts.def
prog-invoke.texi : prog-opts.def
autogen -Taginfo.tpl -bprog-invoke 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.
LICENSING:
This material is copyright (c) 1993-2009 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.

160
libopts/ag-char-map.h Normal file
View File

@@ -0,0 +1,160 @@
/*
* Character mapping generated 08/08/09 10:14:55
*
* This file contains the character classifications
* used by AutoGen and AutoOpts for identifying tokens.
*/
#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>
# else
# ifndef HAVE_INT8_T
typedef signed char int8_t;
# endif
# ifndef HAVE_UINT8_T
typedef unsigned char uint8_t;
# endif
# ifndef HAVE_INT16_T
typedef signed short int16_t;
# endif
# ifndef HAVE_UINT16_T
typedef unsigned short uint16_t;
# endif
# ifndef HAVE_UINT_T
typedef unsigned int uint_t;
# endif
# ifndef HAVE_INT32_T
# if SIZEOF_INT == 4
typedef signed int int32_t;
# elif SIZEOF_LONG == 4
typedef signed long int32_t;
# endif
# endif
# ifndef HAVE_UINT32_T
# if SIZEOF_INT == 4
typedef unsigned int uint32_t;
# elif SIZEOF_LONG == 4
typedef unsigned long uint32_t;
# endif
# endif
# endif /* HAVE_*INT*_H header */
#else /* not HAVE_CONFIG_H -- */
# ifdef __sun
# include <inttypes.h>
# else
# include <stdint.h>
# endif
#endif /* HAVE_CONFIG_H */
#if 0 /* mapping specification source (from autogen.map) */
//
// %guard autoopts_internal
// %file ag-char-map.h
// %table opt-char-cat
//
// %comment
// This file contains the character classifications
// used by AutoGen and AutoOpts for identifying tokens.
// %
//
// lower-case "a-z"
// upper-case "A-Z"
// alphabetic +lower-case +upper-case
// oct-digit "0-7"
// dec-digit "89" +oct-digit
// hex-digit "a-fA-F" +dec-digit
// alphanumeric +alphabetic +dec-digit
// var-first "_" +alphabetic
// variable-name +var-first +dec-digit
// option-name "^-" +variable-name
// value-name ":" +option-name
// horiz-white "\t "
// compound-name "[.]" +value-name +horiz-white
// whitespace "\v\f\r\n\b" +horiz-white
// unquotable "!-~" -"\"#(),;<=>[\\]`{}?*'"
// end-xml-token "/>" +whitespace
// graphic "!-~"
// plus-n-space "+" +whitespace
// punctuation "!-~" -alphanumeric -"_"
// suffix "-._" +alphanumeric
// suffix-fmt "%/" +suffix
// false-type "nNfF0\x00"
//
#endif /* 0 -- mapping spec. source */
typedef uint32_t opt_char_cat_mask_t;
extern opt_char_cat_mask_t const opt_char_cat[128];
static inline int is_opt_char_cat_char(char ch, opt_char_cat_mask_t mask) {
unsigned int ix = (unsigned char)ch;
return ((ix < 0x7F) && ((opt_char_cat[ix] & mask) != 0)); }
#define IS_LOWER_CASE_CHAR(_c) is_opt_char_cat_char((_c), 0x00001)
#define IS_UPPER_CASE_CHAR(_c) is_opt_char_cat_char((_c), 0x00002)
#define IS_ALPHABETIC_CHAR(_c) is_opt_char_cat_char((_c), 0x00003)
#define IS_OCT_DIGIT_CHAR(_c) is_opt_char_cat_char((_c), 0x00004)
#define IS_DEC_DIGIT_CHAR(_c) is_opt_char_cat_char((_c), 0x0000C)
#define IS_HEX_DIGIT_CHAR(_c) is_opt_char_cat_char((_c), 0x0001C)
#define IS_ALPHANUMERIC_CHAR(_c) is_opt_char_cat_char((_c), 0x0000F)
#define IS_VAR_FIRST_CHAR(_c) is_opt_char_cat_char((_c), 0x00023)
#define IS_VARIABLE_NAME_CHAR(_c) is_opt_char_cat_char((_c), 0x0002F)
#define IS_OPTION_NAME_CHAR(_c) is_opt_char_cat_char((_c), 0x0006F)
#define IS_VALUE_NAME_CHAR(_c) is_opt_char_cat_char((_c), 0x000EF)
#define IS_HORIZ_WHITE_CHAR(_c) is_opt_char_cat_char((_c), 0x00100)
#define IS_COMPOUND_NAME_CHAR(_c) is_opt_char_cat_char((_c), 0x003EF)
#define IS_WHITESPACE_CHAR(_c) is_opt_char_cat_char((_c), 0x00500)
#define IS_UNQUOTABLE_CHAR(_c) is_opt_char_cat_char((_c), 0x00800)
#define IS_END_XML_TOKEN_CHAR(_c) is_opt_char_cat_char((_c), 0x01500)
#define IS_GRAPHIC_CHAR(_c) is_opt_char_cat_char((_c), 0x02000)
#define IS_PLUS_N_SPACE_CHAR(_c) is_opt_char_cat_char((_c), 0x04500)
#define IS_PUNCTUATION_CHAR(_c) is_opt_char_cat_char((_c), 0x08000)
#define IS_SUFFIX_CHAR(_c) is_opt_char_cat_char((_c), 0x1000F)
#define IS_SUFFIX_FMT_CHAR(_c) is_opt_char_cat_char((_c), 0x3000F)
#define IS_FALSE_TYPE_CHAR(_c) is_opt_char_cat_char((_c), 0x40000)
#ifdef AUTOOPTS_INTERNAL
opt_char_cat_mask_t const opt_char_cat[128] = {
/*x00*/ 0x40000, /*x01*/ 0x00000, /*x02*/ 0x00000, /*x03*/ 0x00000,
/*x04*/ 0x00000, /*x05*/ 0x00000, /*x06*/ 0x00000, /*\a */ 0x00000,
/*\b */ 0x00400, /*\t */ 0x00100, /*\n */ 0x00400, /*\v */ 0x00400,
/*\f */ 0x00400, /*\r */ 0x00400, /*x0E*/ 0x00000, /*x0F*/ 0x00000,
/*x10*/ 0x00000, /*x11*/ 0x00000, /*x12*/ 0x00000, /*x13*/ 0x00000,
/*x14*/ 0x00000, /*x15*/ 0x00000, /*x16*/ 0x00000, /*x17*/ 0x00000,
/*x18*/ 0x00000, /*x19*/ 0x00000, /*x1A*/ 0x00000, /*x1B*/ 0x00000,
/*x1C*/ 0x00000, /*x1D*/ 0x00000, /*x1E*/ 0x00000, /*x1F*/ 0x00000,
/* */ 0x00100, /* ! */ 0x0A800, /* " */ 0x0A000, /* # */ 0x0A000,
/* $ */ 0x0A800, /* % */ 0x2A800, /* & */ 0x0A800, /* ' */ 0x0A000,
/* ( */ 0x0A000, /* ) */ 0x0A000, /* * */ 0x0A000, /* + */ 0x0E800,
/* , */ 0x0A000, /* - */ 0x1A840, /* . */ 0x1AA00, /* / */ 0x2B800,
/* 0 */ 0x42804, /* 1 */ 0x02804, /* 2 */ 0x02804, /* 3 */ 0x02804,
/* 4 */ 0x02804, /* 5 */ 0x02804, /* 6 */ 0x02804, /* 7 */ 0x02804,
/* 8 */ 0x02808, /* 9 */ 0x02808, /* : */ 0x0A880, /* ; */ 0x0A000,
/* < */ 0x0A000, /* = */ 0x0A000, /* > */ 0x0B000, /* ? */ 0x0A000,
/* @ */ 0x0A800, /* A */ 0x02812, /* B */ 0x02812, /* C */ 0x02812,
/* D */ 0x02812, /* E */ 0x02812, /* F */ 0x42812, /* G */ 0x02802,
/* H */ 0x02802, /* I */ 0x02802, /* J */ 0x02802, /* K */ 0x02802,
/* L */ 0x02802, /* M */ 0x02802, /* N */ 0x42802, /* O */ 0x02802,
/* P */ 0x02802, /* Q */ 0x02802, /* R */ 0x02802, /* S */ 0x02802,
/* T */ 0x02802, /* U */ 0x02802, /* V */ 0x02802, /* W */ 0x02802,
/* X */ 0x02802, /* Y */ 0x02802, /* Z */ 0x02802, /* [ */ 0x0A200,
/* \ */ 0x0A000, /* ] */ 0x0A200, /* ^ */ 0x0A840, /* _ */ 0x12820,
/* ` */ 0x0A000, /* a */ 0x02811, /* b */ 0x02811, /* c */ 0x02811,
/* d */ 0x02811, /* e */ 0x02811, /* f */ 0x42811, /* g */ 0x02801,
/* h */ 0x02801, /* i */ 0x02801, /* j */ 0x02801, /* k */ 0x02801,
/* l */ 0x02801, /* m */ 0x02801, /* n */ 0x42801, /* o */ 0x02801,
/* p */ 0x02801, /* q */ 0x02801, /* r */ 0x02801, /* s */ 0x02801,
/* t */ 0x02801, /* u */ 0x02801, /* v */ 0x02801, /* w */ 0x02801,
/* x */ 0x02801, /* y */ 0x02801, /* z */ 0x02801, /* { */ 0x0A000,
/* | */ 0x0A800, /* } */ 0x0A000, /* ~ */ 0x0A800, /*x7F*/ 0x00000
};
#endif /* AUTOOPTS_INTERNAL */
#endif /* AG_CHAR_MAP_H_GUARD */

1164
libopts/autoopts.c Normal file

File diff suppressed because it is too large Load Diff

364
libopts/autoopts.h Normal file
View File

@@ -0,0 +1,364 @@
/*
* Time-stamp: "2008-11-01 20:08:06 bkorb"
*
* autoopts.h $Id: autoopts.h,v 4.42 2009/08/01 17:43:05 bkorb Exp $
*
* 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-2009 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
#include "compat/compat.h"
#include "ag-char-map.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
#ifndef EX_NOINPUT
# define EX_NOINPUT 66
#endif
#ifndef EX_SOFTWARE
# define EX_SOFTWARE 70
#endif
#ifndef EX_CONFIG
# define EX_CONFIG 78
#endif
/*
* 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_DOCUMENT|OPTST_OMITTED)) != 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)
/*
* 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)
/*
* 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;
extern 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;
extern tePagerState pagerState;
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 {
tCC* pzStr;
tCC* pzReq;
tCC* pzNum;
tCC* pzFile;
tCC* pzKey;
tCC* pzKeyL;
tCC* pzBool;
tCC* pzNest;
tCC* pzOpt;
tCC* pzNo;
tCC* pzBrk;
tCC* pzNoF;
tCC* pzSpc;
tCC* pzOptFmt;
tCC* 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) do{void*X=(void*)_p;ao_free(X);}while(0)
#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 );
static void
ao_free( void *p );
static char *
ao_strdup( char const *str );
#define TAGMEM( m, t )
/*
* 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
*/
extern FILE* option_usage_fp;
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 */

1049
libopts/autoopts/options.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,393 @@
/* -*- buffer-read-only: t -*- vi: set ro:
*
* DO NOT EDIT THIS FILE (usage-txt.h)
*
* It has been AutoGen-ed August 8, 2009 at 10:14:43 AM by AutoGen 5.9.9
* 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 130
* 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.
*
* 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[ 123 ];
} 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_Bad (option_usage_text.apz_str[ 0])
#define zAO_Big (option_usage_text.apz_str[ 1])
#define zAO_Err (option_usage_text.apz_str[ 2])
#define zAO_Sml (option_usage_text.apz_str[ 3])
#define zAO_Ver (option_usage_text.apz_str[ 4])
#define zAO_Woops (option_usage_text.apz_str[ 5])
#define zAll (option_usage_text.apz_str[ 6])
#define zAlt (option_usage_text.apz_str[ 7])
#define zAmbigKey (option_usage_text.apz_str[ 8])
#define zAmbigOptStr (option_usage_text.apz_str[ 9])
#define zArgsMust (option_usage_text.apz_str[ 10])
#define zAtMost (option_usage_text.apz_str[ 11])
#define zAuto (option_usage_text.apz_str[ 12])
#define zBadPipe (option_usage_text.apz_str[ 13])
#define zBadVerArg (option_usage_text.apz_str[ 14])
#define zCantFmt (option_usage_text.apz_str[ 15])
#define zCantSave (option_usage_text.apz_str[ 16])
#define zDefaultOpt (option_usage_text.apz_str[ 17])
#define zDis (option_usage_text.apz_str[ 18])
#define zEnab (option_usage_text.apz_str[ 19])
#define zEquiv (option_usage_text.apz_str[ 20])
#define zErrOnly (option_usage_text.apz_str[ 21])
#define zExamineFmt (option_usage_text.apz_str[ 22])
#define zFiveSpaces (option_usage_text.apz_str[ 23])
#define zFlagOkay (option_usage_text.apz_str[ 24])
#define zFmtFmt (option_usage_text.apz_str[ 25])
#define zForkFail (option_usage_text.apz_str[ 26])
#define zFSErrOptLoad (option_usage_text.apz_str[ 27])
#define zFSErrReadFile (option_usage_text.apz_str[ 28])
#define zFSOptError (option_usage_text.apz_str[ 29])
#define zFSOptErrMayExist (option_usage_text.apz_str[ 30])
#define zFSOptErrMustExist (option_usage_text.apz_str[ 31])
#define zFSOptErrNoExist (option_usage_text.apz_str[ 32])
#define zFSOptErrOpen (option_usage_text.apz_str[ 33])
#define zFSOptErrFopen (option_usage_text.apz_str[ 34])
#define zFileCannotExist (option_usage_text.apz_str[ 35])
#define zFileMustExist (option_usage_text.apz_str[ 36])
#define zGenshell (option_usage_text.apz_str[ 37])
#define zGnuBoolArg (option_usage_text.utpz_GnuBoolArg)
#define zGnuBreak (option_usage_text.apz_str[ 38])
#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[ 39])
#define zGnuNumArg (option_usage_text.utpz_GnuNumArg)
#define zGnuOptArg (option_usage_text.apz_str[ 40])
#define zGnuOptFmt (option_usage_text.apz_str[ 41])
#define zGnuStrArg (option_usage_text.utpz_GnuStrArg)
#define zIllOptChr (option_usage_text.apz_str[ 42])
#define zIllOptStr (option_usage_text.apz_str[ 43])
#define zIllegal (option_usage_text.apz_str[ 44])
#define zIntRange (option_usage_text.apz_str[ 45])
#define zInvalOptDesc (option_usage_text.apz_str[ 46])
#define zLowerBits (option_usage_text.apz_str[ 47])
#define zMembers (option_usage_text.apz_str[ 48])
#define zMisArg (option_usage_text.apz_str[ 49])
#define zMultiEquiv (option_usage_text.apz_str[ 50])
#define zMust (option_usage_text.apz_str[ 51])
#define zNeedOne (option_usage_text.apz_str[ 52])
#define zNoArg (option_usage_text.apz_str[ 53])
#define zNoArgs (option_usage_text.apz_str[ 54])
#define zNoCreat (option_usage_text.apz_str[ 55])
#define zNoFlags (option_usage_text.apz_str[ 56])
#define zNoKey (option_usage_text.apz_str[ 57])
#define zNoLim (option_usage_text.apz_str[ 58])
#define zNoPreset (option_usage_text.apz_str[ 59])
#define zNoResetArg (option_usage_text.apz_str[ 60])
#define zNoRq_NoShrtTtl (option_usage_text.apz_str[ 61])
#define zNoRq_ShrtTtl (option_usage_text.apz_str[ 62])
#define zNoStat (option_usage_text.apz_str[ 63])
#define zNoState (option_usage_text.apz_str[ 64])
#define zNone (option_usage_text.apz_str[ 65])
#define zNotDef (option_usage_text.apz_str[ 66])
#define zNotCmdOpt (option_usage_text.apz_str[ 67])
#define zNotEnough (option_usage_text.apz_str[ 68])
#define zNotFile (option_usage_text.apz_str[ 69])
#define zNotNumber (option_usage_text.apz_str[ 70])
#define zNrmOptFmt (option_usage_text.apz_str[ 71])
#define zNumberOpt (option_usage_text.apz_str[ 72])
#define zOneSpace (option_usage_text.apz_str[ 73])
#define zOnlyOne (option_usage_text.apz_str[ 74])
#define zOptsOnly (option_usage_text.apz_str[ 75])
#define zPathFmt (option_usage_text.apz_str[ 76])
#define zPlsSendBugs (option_usage_text.apz_str[ 77])
#define zPreset (option_usage_text.apz_str[ 78])
#define zPresetFile (option_usage_text.apz_str[ 79])
#define zPresetIntro (option_usage_text.apz_str[ 80])
#define zProg (option_usage_text.apz_str[ 81])
#define zProhib (option_usage_text.apz_str[ 82])
#define zReorder (option_usage_text.apz_str[ 83])
#define zRange (option_usage_text.apz_str[ 84])
#define zRangeAbove (option_usage_text.apz_str[ 85])
#define zRangeLie (option_usage_text.apz_str[ 86])
#define zRangeBadLie (option_usage_text.apz_str[ 87])
#define zRangeOnly (option_usage_text.apz_str[ 88])
#define zRangeOr (option_usage_text.apz_str[ 89])
#define zRangeErr (option_usage_text.apz_str[ 90])
#define zRangeExact (option_usage_text.apz_str[ 91])
#define zRangeScaled (option_usage_text.apz_str[ 92])
#define zRangeUpto (option_usage_text.apz_str[ 93])
#define zResetNotConfig (option_usage_text.apz_str[ 94])
#define zReqFmt (option_usage_text.apz_str[ 95])
#define zReqOptFmt (option_usage_text.apz_str[ 96])
#define zReqThese (option_usage_text.apz_str[ 97])
#define zReq_NoShrtTtl (option_usage_text.apz_str[ 98])
#define zReq_ShrtTtl (option_usage_text.apz_str[ 99])
#define zSepChars (option_usage_text.apz_str[100])
#define zSetMemberSettings (option_usage_text.apz_str[101])
#define zShrtGnuOptFmt (option_usage_text.apz_str[102])
#define zSixSpaces (option_usage_text.apz_str[103])
#define zStdBoolArg (option_usage_text.apz_str[104])
#define zStdBreak (option_usage_text.apz_str[105])
#define zStdFileArg (option_usage_text.apz_str[106])
#define zStdKeyArg (option_usage_text.apz_str[107])
#define zStdKeyLArg (option_usage_text.apz_str[108])
#define zStdTimeArg (option_usage_text.apz_str[109])
#define zStdNestArg (option_usage_text.apz_str[110])
#define zStdNoArg (option_usage_text.apz_str[111])
#define zStdNumArg (option_usage_text.apz_str[112])
#define zStdOptArg (option_usage_text.apz_str[113])
#define zStdReqArg (option_usage_text.apz_str[114])
#define zStdStrArg (option_usage_text.apz_str[115])
#define zTabHyp (option_usage_text.apz_str[116])
#define zTabHypAnd (option_usage_text.apz_str[117])
#define zTabout (option_usage_text.apz_str[118])
#define zThreeSpaces (option_usage_text.apz_str[119])
#define zTwoSpaces (option_usage_text.apz_str[120])
#define zUpTo (option_usage_text.apz_str[121])
#define zValidKeys (option_usage_text.apz_str[122])
/*
* 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[4024] =
"AutoOpts function called without option descriptor\n\0"
"\tThis exceeds the compiled library version: \0"
"Automated Options Processing Error!\n"
"\t%s called AutoOpts function with structure version %d:%d:%d.\n\0"
"\tThis is less than the minimum library version: \0"
"Automated Options version %s\n"
"\tcopyright (c) 1999-2009 by Bruce Korb - all rights reserved\n\0"
"AutoOpts lib error: defaulted to option with optional arg\n\0"
"all\0"
"\t\t\t\t- an alternate for %s\n\0"
"%s error: the keyword `%s' is ambiguous for %s\n\0"
"%s: ambiguous option -- %s\n\0"
"%s: Command line arguments required\n\0"
"%d %s%s options allowed\n\0"
"version and help options:\0"
"Error %d (%s) from the pipe(2) syscall\n\0"
"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"
"ERROR: %s option conflicts with the %s option\n\0"
"%s(optionSaveState): error: cannot allocate %d bytes\n\0"
"\t\t\t\t- default option for unnamed options\n\0"
"\t\t\t\t- disabled as --%s\n\0"
"\t\t\t\t- enabled by default\n\0"
"-equivalence\0"
"ERROR: only \0"
" - examining environment variables named %s_*\n\0"
" \0"
"Options are specified by doubled hyphens and their name\n"
"or by a single hyphen and the flag character.\n\0"
"%%-%ds %%s\n\0"
"fs error %d (%s) on fork - cannot obtain %s usage\n\0"
"File error %d (%s) opening %s for loading options\n\0"
"fs error %d (%s) reading file %s\n\0"
"fs error %d (%s) on %s %s for option %s\n\0"
"stat-ing for directory\0"
"stat-ing for regular file\0"
"stat-ing for non-existant file\0"
"open-ing file\0"
"fopen-ing file\0"
"\t\t\t\t- file must not pre-exist\n\0"
"\t\t\t\t- file must pre-exist\n\0"
"\n"
"= = = = = = = =\n\n"
"This incarnation of genshell will produce\n"
"a shell script to parse the options for %s:\n\n\0"
"\n"
"%s\n\n\0"
"=Cplx\0"
"[=arg]\0"
"--%2$s%1$s\0"
"%s: illegal option -- %c\n\0"
"%s: illegal option -- %s\n\0"
"illegal\0"
" or an integer from %d through %d\n\0"
"AutoOpts ERROR: invalid option descriptor for %s\n\0"
" or an integer mask with any of the lower %d bits set\n\0"
"\t\t\t\t- is a set membership option\n\0"
"%s: option `%s' requires an argument\n\0"
"Equivalenced option '%s' was equivalenced to both\n"
"\t'%s' and '%s'\0"
"\t\t\t\t- must appear between %d and %d times\n\0"
"ERROR: The %s option is required\n\0"
"%s: option `%s' cannot have an argument\n\0"
"%s: Command line arguments not allowed\n\0"
"error %d (%s) creating %s\n\0"
"Options are specified by single or double hyphens and their name.\n\0"
"%s error: `%s' does not match any %s keywords\n\0"
"\t\t\t\t- may appear multiple times\n\0"
"\t\t\t\t- may not be preset\n\0"
"The 'reset-option' option requires an argument\n\0"
" Arg Option-Name Description\n\0"
" Flg Arg Option-Name Description\n\0"
"error %d (%s) stat-ing %s\n\0"
"%s(optionRestore): error: no saved option state\n\0"
"none\0"
"'%s' not defined\n\0"
"'%s' is not a command line option\n\0"
"ERROR: The %s option must appear %d times\n\0"
"error: cannot load options from non-regular file %s\n\0"
"%s error: `%s' is not a recognizable number\n\0"
" %3s %s\0"
"The '-#<number>' option may omit the hash char\n\0"
" \0"
"one %s%s option allowed\n\0"
"All arguments are named options.\n\0"
" - reading file %s\0"
"\n"
"please send bug reports to: %s\n\0"
"\t\t\t\t- may NOT appear - preset only\n\0"
"# preset/initialization file\n"
"# %s#\n\0"
"\n"
"The following option preset mechanisms are supported:\n\0"
"program\0"
"prohibits these options:\n\0"
"Operands and options may be intermixed. They will be reordered.\n\0"
"%s%ld to %ld\0"
"%sgreater than or equal to %ld\0"
"%sIt must lie in one of the ranges:\n\0"
"%sThis option must lie in one of the ranges:\n\0"
"%sit must be: \0"
", or\n\0"
"%s error: %s option value ``%s'' is out of range.\n\0"
"%s%ld exactly\0"
"%sis scalable with a suffix: k/K/m/M/g/G/t/T\n\0"
"%sless than or equal to %ld\0"
"The --reset-option has not been configured.\n\0"
"ERROR: %s option requires the %s option\n\0"
" %3s %-14s %s\0"
"requires these options:\n\0"
" Arg Option-Name Req? Description\n\0"
" Flg Arg Option-Name Req? Description\n\0"
"-_^\0"
"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"
"%s\0"
" \0"
"T/F\0"
"\n"
"%s\n\n"
"%s\0"
"Fil\0"
"KWd\0"
"Mbr\0"
"Tim\0"
"Cpx\0"
"no \0"
"Num\0"
"opt\0"
"YES\0"
"Str\0"
"\t\t\t\t- \0"
"\t\t\t\t-- and \0"
"\t\t\t\t%s\n\0"
" \0"
" \0"
"\t\t\t\t- may appear up to %d times\n\0"
"The valid \"%s\" option keywords are:\n\0";
/*
* 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 = {
130,
eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuFileArg, eng_zGnuKeyLArg,
eng_zGnuTimeArg, eng_zGnuNumArg, eng_zGnuStrArg,
{
usage_txt + 0, usage_txt + 52, usage_txt + 98, usage_txt + 197,
usage_txt + 247, usage_txt + 338, usage_txt + 397, usage_txt + 401,
usage_txt + 428, usage_txt + 477, usage_txt + 505, usage_txt + 542,
usage_txt + 567, usage_txt + 593, usage_txt + 633, usage_txt + 770,
usage_txt + 818, usage_txt + 872, usage_txt + 914, usage_txt + 938,
usage_txt + 964, usage_txt + 977, usage_txt + 991, usage_txt +1038,
usage_txt +1044, usage_txt +1147, usage_txt +1159, usage_txt +1210,
usage_txt +1261, usage_txt +1295, usage_txt +1336, usage_txt +1359,
usage_txt +1385, usage_txt +1416, usage_txt +1430, usage_txt +1445,
usage_txt +1476, usage_txt +1503, usage_txt +1609, usage_txt +1615,
usage_txt +1621, usage_txt +1628, usage_txt +1639, usage_txt +1665,
usage_txt +1691, usage_txt +1699, usage_txt +1735, usage_txt +1786,
usage_txt +1842, usage_txt +1876, usage_txt +1914, usage_txt +1979,
usage_txt +2022, usage_txt +2057, usage_txt +2098, usage_txt +2138,
usage_txt +2165, usage_txt +2232, usage_txt +2280, usage_txt +2313,
usage_txt +2338, usage_txt +2386, usage_txt +2421, usage_txt +2459,
usage_txt +2486, usage_txt +2535, usage_txt +2540, usage_txt +2558,
usage_txt +2593, usage_txt +2637, usage_txt +2691, usage_txt +2737,
usage_txt +2745, usage_txt +2793, usage_txt +2795, usage_txt +2820,
usage_txt +2854, usage_txt +2873, usage_txt +2907, usage_txt +2943,
usage_txt +2981, usage_txt +3037, usage_txt +3045, usage_txt +3071,
usage_txt +3137, usage_txt +3150, usage_txt +3181, usage_txt +3218,
usage_txt +3264, usage_txt +3280, usage_txt +3286, usage_txt +3338,
usage_txt +3352, usage_txt +3398, usage_txt +3426, usage_txt +3471,
usage_txt +3513, usage_txt +3527, usage_txt +3552, usage_txt +3592,
usage_txt +3635, usage_txt +3639, usage_txt +3858, usage_txt +3861,
usage_txt +3868, usage_txt +3872, usage_txt +3880, usage_txt +3884,
usage_txt +3888, usage_txt +3892, usage_txt +3896, usage_txt +3900,
usage_txt +3904, usage_txt +3908, usage_txt +3912, usage_txt +3916,
usage_txt +3920, usage_txt +3927, usage_txt +3939, usage_txt +3947,
usage_txt +3951, usage_txt +3954, usage_txt +3987
}
};
#endif /* DO_TRANSLATIONS */
#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */

91
libopts/boolean.c Normal file
View File

@@ -0,0 +1,91 @@
/*
* $Id: boolean.c,v 4.16 2009/08/01 17:43:05 bkorb Exp $
* Time-stamp: "2008-08-03 13:06:02 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-2009 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;
ag_bool res = AG_TRUE;
if ((pOD->fOptState & OPTST_RESET) != 0)
return;
if (pOD->optArg.argString == NULL) {
pOD->optArg.argBool = AG_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 = AG_FALSE;
break;
case '#':
if (pOD->optArg.argString[1] != 'f')
break;
res = AG_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 */

366
libopts/compat/compat.h Normal file
View File

@@ -0,0 +1,366 @@
/* -*- Mode: C -*- */
/* compat.h --- fake the preprocessor into handlng portability
*
* Time-stamp: "2008-06-14 09:36:25 bkorb"
*
* $Id: compat.h,v 4.22 2009/01/01 16:49:26 bkorb Exp $
*
* compat.h is free software.
* This file is part of AutoGen.
*
* AutoGen copyright (c) 1992-2009 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>
#include <sys/wait.h>
#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
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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;
#endif
#ifndef HAVE_UINT8_T
typedef unsigned char uint8_t;
#endif
#ifndef HAVE_INT16_T
typedef signed short int16_t;
#endif
#ifndef HAVE_UINT16_T
typedef unsigned short uint16_t;
#endif
#ifndef HAVE_UINT_T
typedef unsigned int uint_t;
#endif
#ifndef HAVE_INT32_T
# if SIZEOF_INT == 4
typedef signed int int32_t;
# elif SIZEOF_LONG == 4
typedef signed long int32_t;
# endif
#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
#endif
#ifndef HAVE_INTPTR_T
typedef signed long intptr_t;
#endif
#ifndef HAVE_UINTPTR_T
typedef unsigned long uintptr_t;
#endif
#ifndef HAVE_SIZE_T
typedef unsigned int size_t;
#endif
#ifndef HAVE_WINT_T
typedef unsigned int wint_t;
#endif
#ifndef HAVE_PID_T
typedef signed int pid_t;
#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 */

338
libopts/compat/pathfind.c Normal file
View File

@@ -0,0 +1,338 @@
/* -*- Mode: C -*- */
/* pathfind.c --- find a FILE MODE along PATH */
/*
* Author: Gary V Vaughan <gvaughan@oranda.demon.co.uk>
* Time-stamp: "2006-09-23 19:46:16 bkorb"
* Last Modified: $Date: 2007/10/07 16:54:54 $
* by: bkorb
*
* $Id: pathfind.c,v 4.12 2007/10/07 16:54:54 bkorb Exp $
*/
/* 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 ((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
libopts/compat/snprintf.c Normal file
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
libopts/compat/strchr.c Normal file
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
libopts/compat/strdup.c Normal file
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;
}

View File

@@ -0,0 +1,147 @@
/*
* Time-stamp: "2009-07-22 18:53:59 bkorb"
* by: bkorb
* Last Committed: $Date: 2009/07/23 02:05:55 $
*
* This file is part of AutoGen.
*
* AutoGen copyright (c) 1992-2009 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 */

1251
libopts/configfile.c Normal file

File diff suppressed because it is too large Load Diff

293
libopts/cook.c Normal file
View File

@@ -0,0 +1,293 @@
/*
* $Id: cook.c,v 4.17 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2007-11-16 22:49:11 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-2009 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 forward declarations maintained by mk-fwd */
/* = = = 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, u_int nl )
{
unsigned int res = 1;
switch (*pRes = *pzIn++) {
case NUL: /* NUL - end of input string */
return 0;
case '\r':
if (*pzIn != '\n')
return 1;
res++;
/* FALLTHROUGH */
case '\n': /* 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 = '\n'; 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.
*/
/*=export_func ao_string_cook
* private:
*
* what: concatenate and escape-process strings
* arg: + char* + pzScan + The *MODIFIABLE* input buffer +
* arg: + int* + pLineCt + 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* pLineCt )
{
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 (pLineCt == NULL)
pLineCt = &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 */
pzS++;
scan_for_quote:
while (IS_WHITESPACE_CHAR(*pzS))
if (*(pzS++) == '\n')
(*pLineCt)++;
/*
* IF the next character is a quote character,
* THEN we will concatenate the strings.
*/
switch (*pzS) {
case '"':
case '\'':
break;
case '/':
/*
* Allow for a comment embedded in the concatenated string.
*/
switch (pzS[1]) {
default: return NULL;
case '/':
/*
* Skip to end of line
*/
pzS = strchr( pzS, '\n' );
if (pzS == NULL)
return NULL;
(*pLineCt)++;
break;
case '*':
{
char* p = strstr( pzS+2, "*/" );
/*
* Skip to terminating star slash
*/
if (p == NULL)
return NULL;
while (pzS < p) {
if (*(pzS++) == '\n')
(*pLineCt)++;
}
pzS = p + 2;
}
}
goto scan_for_quote;
default:
/*
* The next non-whitespace character is not a quote.
* The series of quoted strings has come to an end.
*/
return pzS;
}
q = *(pzS++); /* assign new quote character and advance scan */
}
/*
* We are inside a quoted string. Copy text.
*/
switch (*(pzD++) = *(pzS++)) {
case NUL:
return NULL;
case '\n':
(*pLineCt)++;
break;
case '\\':
/*
* IF we are escaping a new line,
* THEN drop both the escape and the newline from
* the result string.
*/
if (*pzS == '\n') {
pzS++;
pzD--;
(*pLineCt)++;
}
/*
* 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, (u_int)'\n' );
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 */

512
libopts/enumeration.c Normal file
View File

@@ -0,0 +1,512 @@
/*
* $Id: enumeration.c,v 4.26 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-07-27 12:28:01 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-2009 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
*/
tSCC* pz_enum_err_fmt;
/* = = = START-STATIC-FORWARD = = = */
/* static forward declarations maintained by mk-fwd */
static void
enumError(
tOptions* pOpts,
tOptDesc* pOD,
tCC* const * paz_names,
int name_ct );
static uintptr_t
findName(
tCC* pzName,
tOptions* pOpts,
tOptDesc* pOD,
tCC* const * paz_names,
unsigned int name_ct );
/* = = = END-STATIC-FORWARD = = = */
static void
enumError(
tOptions* pOpts,
tOptDesc* pOD,
tCC* 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.
*/
{
tCC * 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, " %s\n", *(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( '\n', option_usage_fp );
}
/*
* Otherwise, columnize the output
*/
else {
int ent_no = 0;
char zFmt[16]; /* format for all-but-last entries on a line */
sprintf( zFmt, "%%-%ds", (int)max_len );
max_len = 78 / max_len; /* max_len is now max entries on a line */
fputs( " ", 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, "%s\n ", *(paz_names++) );
ent_no = 0;
}
else
fprintf(option_usage_fp, zFmt, *(paz_names++) );
}
fprintf(option_usage_fp, "%s\n", *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);
}
}
static uintptr_t
findName(
tCC* pzName,
tOptions* pOpts,
tOptDesc* pOD,
tCC* 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;
enumError(pOpts, pOD, paz_names, (int)name_ct);
return name_ct;
}
/*
* 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 */
res = (res != name_ct) ? ~0 : idx; /* save partial match */
}
}
if (res < name_ct)
return res; /* partial match */
pz_enum_err_fmt = (res == name_ct) ? zNoKey : zAmbigKey;
option_usage_fp = stderr;
enumError(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;
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,
tCC * 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.
*/
enumError(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-%d", ix );
else
fputs( paz_names[ ix ], stdout );
break;
}
case (uintptr_t)OPTPROC_RETURN_VALNAME:
{
tSCC zInval[] = "*INVALID*";
unsigned int ix = pOD->optArg.argEnum;
/*
* Replace the enumeration value with the name string.
*/
if (ix >= name_ct)
return (uintptr_t)zInval;
pOD->optArg.argString = paz_names[ix];
break;
}
default:
res = findName(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;
}
/*=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,
tCC* 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:
/*
* print the list of enumeration names.
*/
enumError(OPTPROC_EMIT_USAGE, pOD, paz_names, (int)name_ct );
return;
case (uintptr_t)OPTPROC_EMIT_SHELL:
{
/*
* print the name string.
*/
int ix = 0;
uintptr_t bits = (uintptr_t)pOD->optCookie;
size_t len = 0;
bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
while (bits != 0) {
if (bits & 1) {
if (len++ > 0) fputs( " | ", stdout );
fputs(paz_names[ix], stdout);
}
if (++ix >= name_ct) break;
bits >>= 1;
}
return;
}
case (uintptr_t)OPTPROC_RETURN_VALNAME:
{
char* pz;
uintptr_t bits = (uintptr_t)pOD->optCookie;
int ix = 0;
size_t len = 5;
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]) + 8;
if (++ix >= name_ct) break;
bits >>= 1;
}
pOD->optArg.argString = pz = AGALOC(len, "enum name");
/*
* 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.
*/
strcpy( pz, "none" );
pz += 4;
bits = (uintptr_t)pOD->optCookie;
bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
ix = 0;
while (bits != 0) {
if (bits & 1) {
strcpy( pz, " + " );
strcpy( pz+3, paz_names[ix]);
pz += strlen( paz_names[ix]) + 3;
}
if (++ix >= name_ct) break;
bits >>= 1;
}
return;
}
default:
break;
}
if ((pOD->fOptState & OPTST_RESET) != 0)
return;
{
tCC* pzArg = pOD->optArg.argString;
uintptr_t res;
if ((pzArg == NULL) || (*pzArg == NUL)) {
pOD->optCookie = (void*)0;
return;
}
res = (uintptr_t)pOD->optCookie;
for (;;) {
tSCC zSpn[] = " ,|+\t\r\f\n";
int iv, len;
pzArg += strspn( pzArg, zSpn );
iv = (*pzArg == '!');
if (iv)
pzArg += strspn( pzArg+1, zSpn ) + 1;
len = strcspn( pzArg, zSpn );
if (len == 0)
break;
if ((len == 3) && (strncmp(pzArg, zAll, (size_t)3) == 0)) {
if (iv)
res = 0;
else res = ~0UL;
}
else if ((len == 4) && (strncmp(pzArg, zNone, (size_t)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 ];
tCC* p;
int shift_ct;
if (*pz != NUL) {
if (len >= AO_NAME_LIMIT)
break;
strncpy( z, pzArg, (size_t)len );
z[len] = NUL;
p = z;
} else {
p = pzArg;
}
shift_ct = findName(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 (0);
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 */

241
libopts/environment.c Normal file
View File

@@ -0,0 +1,241 @@
/*
* $Id: environment.c,v 4.21 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2009-07-20 20:12:24 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-2009 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 forward declarations maintained by mk-fwd */
static void
checkEnvOpt(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
* doImmediateOpts and/or doRegularOpts.
*/
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 ....
*/
pOpts->origArgVect = (char**)(pTL->tkn_list - 1);
pOpts->origArgCt = pTL->tkn_ct + 1;
pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
pOpts->curOptIdx = 1;
pOpts->pzCurOpt = NULL;
switch (type) {
case ENV_IMM:
(void)doImmediateOpts( pOpts );
break;
case ENV_ALL:
(void)doImmediateOpts( pOpts );
pOpts->curOptIdx = 1;
pOpts->pzCurOpt = NULL;
/* FALLTHROUGH */
case ENV_NON_IMM:
(void)doRegularOpts( 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
checkEnvOpt(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 (os->pzOptArg != NULL) {
if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) {
os->pzOptArg = NULL;
} else if ( (os->pOD->fOptState & OPTST_ARG_OPTIONAL)
&& (*os->pzOptArg == NUL)) {
os->pzOptArg = NULL;
} else if (*os->pzOptArg == NUL) {
os->pzOptArg = zNil;
} else {
AGDUPSTR( os->pzOptArg, os->pzOptArg, "option argument" );
os->flags |= OPTST_ALLOC_ARG;
}
}
handleOption( pOpts, os );
}
/*
* doEnvPresets - check for preset values from the envrionment
* This routine should process in all, immediate or normal modes....
*/
LOCAL void
doEnvPresets( 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++) {
/*
* 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.
*/
if (strlen( st.pOD->pz_NAME ) >= spaceLeft)
continue;
/*
* Set up the option state
*/
strcpy( pzFlagName, st.pOD->pz_NAME );
checkEnvOpt(&st, zEnvName, pOpts, type);
}
/*
* Special handling for ${PROGNAME_LOAD_OPTS}
*/
if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
&& (pOpts->specOptIdx.save_opts != 0)) {
st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
strcpy( pzFlagName, st.pOD->pz_NAME );
checkEnvOpt(&st, zEnvName, pOpts, type);
}
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/environment.c */

170
libopts/file.c Normal file
View File

@@ -0,0 +1,170 @@
/*
* $Id: file.c,v 4.9 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2009-07-23 17:23:46 bkorb"
*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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 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;
}
{
struct stat sb;
errno = 0;
switch (ftype & FTYPE_MODE_EXIST_MASK) {
case FTYPE_MODE_MUST_NOT_EXIST:
if ( (stat(pOD->optArg.argString, &sb) == 0)
|| (errno != ENOENT) ){
if (errno == 0)
errno = EINVAL;
fprintf(stderr, zFSOptError, errno, strerror(errno),
zFSOptErrNoExist, pOD->optArg.argString, pOD->pz_Name);
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
/* NOTREACHED */
}
/* FALLTHROUGH */
default:
case FTYPE_MODE_MAY_EXIST:
{
char * p = strrchr(pOD->optArg.argString, DIRCH);
if (p != NULL)
*p = NUL;
if ( (stat(pOD->optArg.argString, &sb) != 0)
|| (errno = EINVAL, ! S_ISDIR(sb.st_mode)) ){
fprintf(stderr, zFSOptError, errno, strerror(errno),
zFSOptErrMayExist, pOD->optArg.argString, pOD->pz_Name);
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
/* NOTREACHED */
}
if (p != NULL)
*p = DIRCH;
break;
}
case FTYPE_MODE_MUST_EXIST:
if ( (stat(pOD->optArg.argString, &sb) != 0)
|| (errno = EINVAL, ! S_ISREG(sb.st_mode)) ){
fprintf(stderr, zFSOptError, errno, strerror(errno),
zFSOptErrMustExist, pOD->optArg.argString,
pOD->pz_Name);
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
/* NOTREACHED */
}
break;
}
}
switch (ftype & FTYPE_MODE_OPEN_MASK) {
default:
case FTYPE_MODE_NO_OPEN:
break;
case FTYPE_MODE_OPEN_FD:
{
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;
break;
}
case FTYPE_MODE_FOPEN_FP:
{
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;
break;
}
}
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/file.c */

358
libopts/genshell.c Normal file
View File

@@ -0,0 +1,358 @@
/* -*- buffer-read-only: t -*- vi: set ro:
*
* DO NOT EDIT THIS FILE (genshell.c)
*
* It has been AutoGen-ed August 8, 2009 at 10:14:45 AM by AutoGen 5.9.9
* From the definitions genshell.def
* and the template file options
*
* Generated from AutoOpts @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ templates.
*/
/*
* This file was produced by an AutoOpts template. 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.
*
* This source file is copyrighted and licensed under the following terms:
*
* genshellopt copyright (c) 1999-2009 Bruce Korb - all rights reserved
*
* 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/>.
*/
#include <sys/types.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define OPTION_CODE_COMPILE 1
#include "genshell.h"
#ifdef __cplusplus
extern "C" {
#endif
/* TRANSLATORS: choose the translation for option names wisely because you
cannot ever change your mind. */
tSCC zCopyright[] =
"genshellopt copyright (c) 1999-2009 Bruce Korb, all rights reserved";
tSCC zCopyrightNotice[610] =
"genshellopt is free software: you can redistribute it and/or modify it under\n\
the terms of the GNU General Public License as published by the Free Software\n\
Foundation, either version 3 of the License, or (at your option) any later\n\
version.\n\n\
genshellopt is distributed in the hope that it will be useful, but WITHOUT ANY\n\
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\n\
PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\n\
You should have received a copy of the GNU General Public License along with\n\
this program. If not, see <http://www.gnu.org/licenses/>.";
extern tUsageProc genshelloptUsage;
#ifndef NULL
# define NULL 0
#endif
#ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
# define EXIT_FAILURE 1
#endif
/*
* Script option description:
*/
tSCC zScriptText[] =
"Output Script File";
tSCC zScript_NAME[] = "SCRIPT";
tSCC zScript_Name[] = "script";
#define SCRIPT_FLAGS (OPTST_DISABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
/*
* Shell option description:
*/
tSCC zShellText[] =
"Shell name (follows \"#!\" magic)";
tSCC zShell_NAME[] = "SHELL";
tSCC zNotShell_Name[] = "no-shell";
tSCC zNotShell_Pfx[] = "no";
#define zShell_Name (zNotShell_Name + 3)
#define SHELL_FLAGS (OPTST_INITENABLED \
| OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
/*
* Help/More_Help/Version option descriptions:
*/
tSCC zHelpText[] = "Display usage information and exit";
tSCC zHelp_Name[] = "help";
tSCC zMore_HelpText[] = "Extended usage information passed thru pager";
tSCC zMore_Help_Name[] = "more-help";
tSCC zVersionText[] = "Output version information and exit";
tSCC zVersion_Name[] = "version";
/*
* Declare option callback procedures
*/
extern tOptProc
optionPagedUsage, optionPrintVersion;
static tOptProc
doUsageOpt;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Define the Genshellopt Option Descriptions.
*/
static tOptDesc optDesc[ OPTION_CT ] = {
{ /* entry idx, value */ 0, VALUE_OPT_SCRIPT,
/* equiv idx, value */ 0, VALUE_OPT_SCRIPT,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SCRIPT_FLAGS, 0,
/* last opt argumnt */ { NULL },
/* arg list/cookie */ NULL,
/* must/cannot opts */ NULL, NULL,
/* option proc */ NULL,
/* desc, NAME, name */ zScriptText, zScript_NAME, zScript_Name,
/* disablement strs */ NULL, NULL },
{ /* entry idx, value */ 1, VALUE_OPT_SHELL,
/* equiv idx, value */ 1, VALUE_OPT_SHELL,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ SHELL_FLAGS, 0,
/* last opt argumnt */ { NULL },
/* arg list/cookie */ NULL,
/* must/cannot opts */ NULL, NULL,
/* option proc */ NULL,
/* desc, NAME, name */ zShellText, zShell_NAME, zShell_Name,
/* disablement strs */ zNotShell_Name, zNotShell_Pfx },
#ifdef NO_OPTIONAL_OPT_ARGS
# define VERSION_OPT_FLAGS OPTST_IMM | OPTST_NO_INIT
#else
# define VERSION_OPT_FLAGS OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \
OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT
#endif
{ /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION,
/* equiv idx value */ NO_EQUIVALENT, 0,
/* equivalenced to */ NO_EQUIVALENT,
/* min, max, act ct */ 0, 1, 0,
/* opt state flags */ VERSION_OPT_FLAGS, 0,
/* last opt argumnt */ { NULL },
/* arg list/cookie */ NULL,
/* must/cannot opts */ NULL, NULL,
/* option proc */ optionPrintVersion,
/* desc, NAME, name */ zVersionText, NULL, zVersion_Name,
/* disablement strs */ NULL, NULL },
#undef VERSION_OPT_FLAGS
{ /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP,
/* equiv idx value */ NO_EQUIVALENT, 0,
/* 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 */ zHelpText, NULL, zHelp_Name,
/* disablement strs */ NULL, NULL },
{ /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP,
/* equiv idx value */ NO_EQUIVALENT, 0,
/* 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 */ optionPagedUsage,
/* desc, NAME, name */ zMore_HelpText, NULL, zMore_Help_Name,
/* disablement strs */ NULL, NULL }
};
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Define the Genshellopt Option Environment
*/
tSCC zPROGNAME[] = "GENSHELLOPT";
tSCC zUsageTitle[] =
"genshellopt - Generate Shell Option Processing Script - Ver. 1\n\
USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n";
#define zRcName NULL
#define apzHomeList NULL
tSCC zBugsAddr[] = "autogen-users@lists.sourceforge.net";
tSCC zExplain[] = "\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\n\
will be extracted from the script file.\n";
tSCC zDetail[] = "\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";
tSCC zFullVersion[] = GENSHELLOPT_FULL_VERSION;
/* extracted from optcode.tpl near line 501 */
#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
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, zCopyrightNotice,
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_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
};
/*
* Create the static procedure(s) declared above.
*/
static void
doUsageOpt(
tOptions* pOptions,
tOptDesc* pOptDesc )
{
(void)pOptions;
USAGE( EXIT_SUCCESS );
}
/* extracted from optcode.tpl near line 633 */
#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);
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( EXIT_FAILURE );
}
return pzRes;
}
static void coerce_it(void** s) { *s = AO_gettext(*s); }
#define COERSION(_f) \
coerce_it((void*)&(genshelloptOptions._f))
/*
* This invokes the translation code (e.g. gettext(3)).
*/
static void
translate_option_strings( void )
{
/*
* 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 = genshelloptOptions.pOptDesc;
char** ppz = (char**)(void*)&(option_usage_text);
int ix = option_usage_text.field_ct;
do {
ppz++;
*ppz = AO_gettext(*ppz);
} while (--ix > 0);
COERSION(pzCopyright);
COERSION(pzCopyNotice);
COERSION(pzFullVersion);
COERSION(pzUsageTitle);
COERSION(pzExplain);
COERSION(pzDetail);
option_usage_text.field_ct = 0;
for (ix = genshelloptOptions.optCt; ix > 0; ix--, pOD++)
coerce_it((void*)&(pOD->pzText));
}
if ((genshelloptOptions.fOptSet & OPTPROC_NXLAT_OPT_CFG) == 0) {
tOptDesc* pOD = genshelloptOptions.pOptDesc;
int ix;
for (ix = genshelloptOptions.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 */

165
libopts/genshell.h Normal file
View File

@@ -0,0 +1,165 @@
/* -*- buffer-read-only: t -*- vi: set ro:
*
* DO NOT EDIT THIS FILE (genshell.h)
*
* It has been AutoGen-ed August 8, 2009 at 10:14:45 AM by AutoGen 5.9.9
* From the definitions genshell.def
* and the template file options
*
* Generated from AutoOpts @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ templates.
*/
/*
* This file was produced by an AutoOpts template. 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.
*
* This source file is copyrighted and licensed under the following terms:
*
* genshellopt copyright (c) 1999-2009 Bruce Korb - all rights reserved
*
* 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 131074
#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_SCRIPT = 0,
INDEX_OPT_SHELL = 1,
INDEX_OPT_VERSION = 2,
INDEX_OPT_HELP = 3,
INDEX_OPT_MORE_HELP = 4
} teOptIndex;
#define OPTION_CT 5
#define GENSHELLOPT_VERSION "1"
#define GENSHELLOPT_FULL_VERSION "genshellopt - Generate Shell Option Processing Script - Ver. 1"
/*
* Interface defines for all options. Replace "n" with the UPPER_CASED
* option name (as in the teOptIndex enumeration above).
* e.g. HAVE_OPT( SCRIPT )
*/
#define DESC(n) (genshelloptOptions.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 )
/* * * * * *
*
* Interface defines for specific options.
*/
#define VALUE_OPT_SCRIPT 'o'
#define VALUE_OPT_SHELL 's'
#define VALUE_OPT_HELP '?'
#define VALUE_OPT_MORE_HELP '!'
#define VALUE_OPT_VERSION 'v'
/*
* Interface defines not associated with particular options
*/
#define ERRSKIP_OPTERR STMTS( genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP )
#define ERRSTOP_OPTERR STMTS( genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP )
#define RESTART_OPT(n) STMTS( \
genshelloptOptions.curOptIdx = (n); \
genshelloptOptions.pzCurOpt = NULL )
#define START_OPT RESTART_OPT(1)
#define USAGE(c) (*genshelloptOptions.pUsageProc)( &genshelloptOptions, c )
/* extracted from opthead.tpl near line 409 */
/* * * * * *
*
* Declare the genshellopt option descriptor.
*/
#ifdef __cplusplus
extern "C" {
#endif
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 */

38
libopts/libopts.c Normal file
View File

@@ -0,0 +1,38 @@
#define AUTOOPTS_INTERNAL
#include "compat/compat.h"
#define LOCAL static
#include "autoopts/options.h"
#include "autoopts/usage-txt.h"
#include "genshell.h"
#include "xat-attribute.h"
#include "value-type.h"
#include "ag-char-map.h"
#include "autoopts.h"
#include "proto.h"
#include "value-type.c"
#include "xat-attribute.c"
#include "autoopts.c"
#include "boolean.c"
#include "configfile.c"
#include "cook.c"
#include "enumeration.c"
#include "environment.c"
#include "file.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 "tokenize.c"
#include "time.c"
#include "usage.c"
#include "version.c"

540
libopts/load.c Normal file
View File

@@ -0,0 +1,540 @@
/*
* $Id: load.c,v 4.38 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-12-06 10:16:05 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-2009 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
*/
tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED;
/* = = = START-STATIC-FORWARD = = = */
/* static forward declarations maintained by mk-fwd */
static ag_bool
insertProgramPath(
char* pzBuf,
int bufSize,
tCC* pzName,
tCC* pzProgPath );
static ag_bool
insertEnvVal(
char* pzBuf,
int bufSize,
tCC* pzName,
tCC* pzProgPath );
static char*
assembleArgValue( 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: ag_bool
* ret-desc: AG_TRUE if the name was handled, otherwise AG_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, carefully 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{AG_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).
=*/
ag_bool
optionMakePath(
char* pzBuf,
int bufSize,
tCC* pzName,
tCC* pzProgPath )
{
size_t name_len = strlen( pzName );
# ifndef PKGDATADIR
# define PKGDATADIR ""
# endif
tSCC pkgdatadir[] = PKGDATADIR;
ag_bool res = AG_TRUE;
if (bufSize <= name_len)
return AG_FALSE;
/*
* IF not an environment variable, just copy the data
*/
if (*pzName != '$') {
tCC* pzS = pzName;
char* pzD = pzBuf;
int ct = bufSize;
for (;;) {
if ( (*(pzD++) = *(pzS++)) == NUL)
break;
if (--ct <= 0)
return AG_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 AG_FALSE;
case '$':
res = insertProgramPath( pzBuf, bufSize, pzName, pzProgPath );
break;
case '@':
if (pkgdatadir[0] == NUL)
return AG_FALSE;
if (name_len + sizeof (pkgdatadir) > bufSize)
return AG_FALSE;
strcpy(pzBuf, pkgdatadir);
strcpy(pzBuf + sizeof(pkgdatadir) - 1, pzName + 2);
break;
default:
res = insertEnvVal( pzBuf, bufSize, pzName, pzProgPath );
}
if (! res)
return AG_FALSE;
#if defined(HAVE_CANONICALIZE_FILE_NAME)
{
char* pz = canonicalize_file_name(pzBuf);
if (pz == NULL)
return AG_FALSE;
if (strlen(pz) < bufSize)
strcpy(pzBuf, pz);
free(pz);
}
#elif defined(HAVE_REALPATH)
{
char z[ PATH_MAX+1 ];
if (realpath( pzBuf, z ) == NULL)
return AG_FALSE;
if (strlen(z) < bufSize)
strcpy( pzBuf, z );
}
#endif
return AG_TRUE;
}
static ag_bool
insertProgramPath(
char* pzBuf,
int bufSize,
tCC* pzName,
tCC* pzProgPath )
{
tCC* pzPath;
tCC* pz;
int skip = 2;
switch (pzName[2]) {
case DIRCH:
skip = 3;
case NUL:
break;
default:
return AG_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 AG_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 AG_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) >= bufSize)
return AG_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 AG_TRUE;
}
static ag_bool
insertEnvVal(
char* pzBuf,
int bufSize,
tCC* pzName,
tCC* pzProgPath )
{
char* pzDir = pzBuf;
for (;;) {
int ch = (int)*++pzName;
if (! IS_VALUE_NAME_CHAR(ch))
break;
*(pzDir++) = (char)ch;
}
if (pzDir == pzBuf)
return AG_FALSE;
*pzDir = NUL;
pzDir = getenv( pzBuf );
/*
* Environment value not found -- skip the home list entry
*/
if (pzDir == NULL)
return AG_FALSE;
if (strlen( pzDir ) + 1 + strlen( pzName ) >= bufSize)
return AG_FALSE;
sprintf( pzBuf, "%s%s", pzDir, pzName );
return AG_TRUE;
}
LOCAL void
mungeString( char* pzTxt, tOptionLoadMode mode )
{
char* pzE;
if (mode == OPTION_LOAD_KEEP)
return;
if (IS_WHITESPACE_CHAR(*pzTxt)) {
char* pzS = pzTxt;
char* pzD = pzTxt;
while (IS_WHITESPACE_CHAR(*++pzS)) ;
while ((*(pzD++) = *(pzS++)) != NUL) ;
pzE = pzD-1;
} else
pzE = pzTxt + strlen( pzTxt );
while ((pzE > pzTxt) && IS_WHITESPACE_CHAR(pzE[-1])) 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*
assembleArgValue( char* pzTxt, tOptionLoadMode mode )
{
tSCC zBrk[] = " \t\n:=";
char* pzEnd = strpbrk( pzTxt, zBrk );
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;
while (IS_WHITESPACE_CHAR(*pzEnd)) pzEnd++;
if (space_break && ((*pzEnd == ':') || (*pzEnd == '=')))
while (IS_WHITESPACE_CHAR(*++pzEnd)) ;
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 )
{
while (IS_WHITESPACE_CHAR(*pzLine)) pzLine++;
{
char* pzArg = assembleArgValue( pzLine, load_mode );
if (! SUCCESSFUL( longOptionFind( 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;
handleOption( 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,
tCC* 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 */

548
libopts/m4/libopts.m4 Normal file
View File

@@ -0,0 +1,548 @@
dnl -*- buffer-read-only: t -*- vi: set ro:
dnl
dnl DO NOT EDIT THIS FILE (libopts.m4)
dnl
dnl It has been AutoGen-ed August 8, 2009 at 10:14:46 AM by AutoGen 5.9.9
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],[
[if test X${INVOKE_LIBOPTS_MACROS_FIRST_done} != Xyes ; then]
# =================
# AC_HEADER_STDC
# =================
AC_HEADER_STDC
# =================
# AC_HEADER_DIRENT
# =================
AC_HEADER_DIRENT
# =================
# AC_CHECK_HEADERS
# =================
AC_CHECK_HEADERS(dlfcn.h errno.h fcntl.h libgen.h memory.h netinet/in.h \
setjmp.h 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 unistd.h \
utime.h sysexits.h)
# --------------------------------------------
# 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
# ================================================
# AC_CHECK_HEADERS: stdarg.h is present define HAVE_STDARG_H, otherwise
# if varargs.h is present define HAVE_VARARGS_H.
# ================================================
AC_CHECK_HEADERS(stdarg.h varargs.h, break)
[if test `eval echo '${'$as_ac_Header'}'` != yes; then]
AC_MSG_ERROR([You must have stdarg.h or varargs.h on your system])
fi
# ================================================
# Similarly for the string.h and strings.h headers
# ================================================
AC_CHECK_HEADERS(string.h strings.h, break)
[if test `eval echo '${'$as_ac_Header'}'` != yes; then]
AC_MSG_ERROR([You must have string.h or strings.h on your system])
fi
# =====================
# ...and limits headers
# =====================
AC_CHECK_HEADERS(limits.h sys/limits.h values.h, break)
[if test `eval echo '${'$as_ac_Header'}'` != yes; then]
AC_MSG_ERROR([You must have one of limits.h, sys/limits.h or values.h])
fi
# ----------------------------------------------------------------------
# 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
])
# ----------------------------------------------------------------------
# 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
])
# ========================
# ...and int types headers
# ========================
AC_CHECK_HEADERS(stdint.h inttypes.h, break)
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])
# =====
# sizes
# =====
AC_CHECK_SIZEOF(char*, 4)
AC_CHECK_SIZEOF(int, 4)
AC_CHECK_SIZEOF(long, 4)
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_CHECK_FUNCS([mmap canonicalize_file_name snprintf strdup strchr \
strrchr strsignal])
[ INVOKE_LIBOPTS_MACROS_FIRST_done=yes
fi]])
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],
AC_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],
AC_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_libguile+set}" = set && \
test "${withval}" = no
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],
AC_HELP_STRING([--with-libregex-cflags], [libregex compile flags]),
[libopts_cv_with_libregex_cflags=${with_regex_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],
AC_HELP_STRING([--with-libregex-libs], [libregex link command arguments]),
[libopts_cv_with_libregex_libs=${with_regex_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
then libopts_cv_test_dev_zero=no
elif 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],
AC_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],[
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: "2009-07-22 18:50:49 bkorb"
dnl Last Committed: $Date: 2009/07/23 02:05:55 $
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-2009 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],[
[NEED_LIBOPTS_DIR='']
m4_pushdef([AO_Libopts_Dir],
[ifelse($1, , [libopts], [$1])])
AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir)
AC_ARG_ENABLE([local-libopts],
AC_HELP_STRING([--enable-local-libopts],
[Force using the supplied libopts tearoff code]),[
if test x$enableval = xyes ; then
AC_MSG_NOTICE([Using supplied libopts tearoff])
LIBOPTS_LDADD='$(top_builddir)/AO_Libopts_Dir/libopts.la'
LIBOPTS_CFLAGS='-I$(top_srcdir)/AO_Libopts_Dir'
NEED_LIBOPTS_DIR=true
fi])
AC_ARG_ENABLE([libopts-install],
AC_HELP_STRING([--disable-libopts-install],
[Do not install libopts with client installation]))
AM_CONDITIONAL([INSTALL_LIBOPTS],[test "X${enable_libopts_install}" != Xno])
[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}"]
AM_CONDITIONAL([NEED_LIBOPTS], [test -n "${NEED_LIBOPTS_DIR}"])
AC_SUBST(LIBOPTS_LDADD)
AC_SUBST(LIBOPTS_CFLAGS)
AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir)
AC_CONFIG_FILES(AO_Libopts_Dir/Makefile)
m4_popdef([AO_Libopts_Dir])
[if test -n "${NEED_LIBOPTS_DIR}" ; then]
INVOKE_LIBOPTS_MACROS
else
INVOKE_LIBOPTS_MACROS_FIRST
[fi
# end of AC_DEFUN of LIBOPTS_CHECK]
])

43
libopts/m4/liboptschk.m4 Normal file
View File

@@ -0,0 +1,43 @@
# liboptschk.m4 serial 1 (autogen - 5.7.3)
dnl copyright (c) 2005-2009 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 Time-stamp: "2009-07-22 18:53:27 bkorb"
dnl Last Committed: $Date: 2009/07/23 02:05:55 $
dnl This file can can be used in projects which are not available under
dnl the GNU General Public License or the GNU Library General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Library General Public License, and the rest of the GNU
dnl gettext package package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Authors:
dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
AC_PREREQ(2.50)
AC_DEFUN([ag_FIND_LIBOPTS],
[if test "X${ac_cv_header_autoopts_options_h}" == Xno
then
:
else
f=`autoopts-config cflags` 2>/dev/null
test X"${f}" = X && f=`libopts-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}"
f=`autoopts-config ldflags` 2>/dev/null
test X"${f}" = X && f=`libopts-config ldflags` 2>/dev/null
LIBS="${LIBS} ${f}"
fi
fi])

1099
libopts/makeshell.c Normal file

File diff suppressed because it is too large Load Diff

843
libopts/nested.c Normal file
View File

@@ -0,0 +1,843 @@
/*
* $Id: nested.c,v 4.32 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-07-28 19:18:28 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-2009 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;" }
};
/* = = = START-STATIC-FORWARD = = = */
/* static forward declarations maintained by mk-fwd */
static void
removeLineContinue( char* pzSrc );
static char const*
scanQuotedString( char const* pzTxt );
static tOptionValue*
addStringValue( void** pp, char const* pzName, size_t nameLen,
char const* pzValue, size_t dataLen );
static tOptionValue*
addBoolValue( void** pp, char const* pzName, size_t nameLen,
char const* pzValue, size_t dataLen );
static tOptionValue*
addNumberValue( void** pp, char const* pzName, size_t nameLen,
char const* pzValue, size_t dataLen );
static tOptionValue*
addNestedValue( void** pp, char const* pzName, size_t nameLen,
char* pzValue, size_t dataLen );
static char const*
scanNameEntry(char const* pzName, tOptionValue* pRes);
static char const*
scanXmlEntry( char const* pzName, tOptionValue* pRes );
static void
unloadNestedArglist( tArgList* pAL );
static void
sortNestedList( tArgList* pAL );
/* = = = END-STATIC-FORWARD = = = */
/* removeLineContinue
*
* Backslashes are used for line continuations. We keep the newline
* characters, but trim out the backslash:
*/
static void
removeLineContinue( char* pzSrc )
{
char* pzD;
do {
while (*pzSrc == '\n') pzSrc++;
pzD = strchr(pzSrc, '\n');
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 == '\n')
--pzD; /* rewrite on next iteration */
}
}
}
/* scanQuotedString
*
* Find the end of a quoted string, skipping escaped quote characters.
*/
static char const*
scanQuotedString( 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;
}
}
}
}
/* addStringValue
*
* Associate a name with either a string or no value.
*/
static tOptionValue*
addStringValue( 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++) = 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;
}
/* addBoolValue
*
* Associate a name with either a string or no value.
*/
static tOptionValue*
addBoolValue( 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.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;
}
/* addNumberValue
*
* Associate a name with either a string or no value.
*/
static tOptionValue*
addNumberValue( 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;
}
/* addNestedValue
*
* Associate a name with either a string or no value.
*/
static tOptionValue*
addNestedValue( 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;
}
/* scanNameEntry
*
* 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*
scanNameEntry(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.
*/
while (IS_VALUE_NAME_CHAR(*pzScan)) { pzScan++; nameLen++; }
if (pzScan[-1] == ':') { pzScan--; nameLen--; }
while (IS_HORIZ_WHITE_CHAR(*pzScan)) pzScan++;
re_switch:
switch (*pzScan) {
case '=':
case ':':
while (IS_HORIZ_WHITE_CHAR( (int)*++pzScan )) ;
if ((*pzScan == '=') || (*pzScan == ':'))
goto default_char;
goto re_switch;
case '\n':
case ',':
pzScan++;
/* FALLTHROUGH */
case NUL:
addStringValue(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
break;
case '"':
case '\'':
pzVal = pzScan;
pzScan = scanQuotedString( pzScan );
dataLen = pzScan - pzVal;
pNV = addStringValue( &(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 '\n':
if ( (pzScan > pzVal + 2)
&& (pzScan[-2] == '\\')
&& (pzScan[ 0] != NUL))
continue;
/* FALLTHROUGH */
case ',':
dataLen = (pzScan - pzVal) - 1;
string_done:
pNV = addStringValue( &(pRes->v.nestVal), pzName, nameLen,
pzVal, dataLen );
if (pNV != NULL)
removeLineContinue( pNV->v.strVal );
goto leave_scan_name;
}
}
break;
} leave_scan_name:;
return pzScan;
}
/* scanXmlEntry
*
* 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*
scanXmlEntry( char const* pzName, tOptionValue* pRes )
{
size_t nameLen = 1, valLen = 0;
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++;
while (IS_VALUE_NAME_CHAR( (int)*pzScan )) { pzScan++; nameLen++; }
if (nameLen > 64)
return NULL;
valu.valType = OPARG_TYPE_STRING;
switch (*pzScan) {
case ' ':
case '\t':
pzScan = parseAttributes(
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;
}
addStringValue(&(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;
while (IS_WHITESPACE_CHAR(*pzScan)) pzScan++;
}
switch (valu.valType) {
case OPARG_TYPE_NONE:
addStringValue( &(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
break;
case OPARG_TYPE_STRING:
pNewVal = addStringValue(
&(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:
addBoolValue( &(pRes->v.nestVal), pzName, nameLen, pzVal, valLen );
break;
case OPARG_TYPE_NUMERIC:
addNumberValue( &(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;
addNestedValue( &(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;
}
/* unloadNestedArglist
*
* 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.
*/
static void
unloadNestedArglist( tArgList* pAL )
{
int ct = pAL->useCt;
tCC** ppNV = pAL->apzArgs;
while (ct-- > 0) {
tOptionValue* pNV = (tOptionValue*)(void*)*(ppNV++);
if (pNV->valType == OPARG_TYPE_HIERARCHY)
unloadNestedArglist( 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;
}
unloadNestedArglist( pOV->v.nestVal );
AGFREE( (void*)pOV );
}
/* sortNestedList
*
* 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
sortNestedList( 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;
}
}
/* optionLoadNested
* 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.
*/
LOCAL tOptionValue*
optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen)
{
tOptionValue* pRes;
tArgList* pAL;
/*
* Make sure we have some data and we have space to put what we find.
*/
if (pzTxt == NULL) {
errno = EINVAL;
return NULL;
}
while (IS_WHITESPACE_CHAR(*pzTxt)) pzTxt++;
if (*pzTxt == NUL) {
errno = ENOENT;
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;
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 {
while (IS_WHITESPACE_CHAR( (int)*pzTxt )) pzTxt++;
if (IS_VAR_FIRST_CHAR( (int)*pzTxt )) {
pzTxt = scanNameEntry( pzTxt, pRes );
}
else switch (*pzTxt) {
case NUL: goto scan_done;
case '<': pzTxt = scanXmlEntry( pzTxt, pRes );
if (pzTxt == NULL) goto woops;
if (*pzTxt == ',') pzTxt++; break;
case '#': pzTxt = strchr( pzTxt, '\n' ); break;
default: goto woops;
}
} while (pzTxt != NULL); scan_done:;
pAL = pRes->v.nestVal;
if (pAL->useCt != 0) {
sortNestedList( pAL );
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, "#x%02X;", (ch & 0xFF));
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/nested.c */

176
libopts/numeric.c Normal file
View File

@@ -0,0 +1,176 @@
/*
* $Id: numeric.c,v 4.22 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2009-07-23 17:25:39 bkorb"
*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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)
{
static char const bullet[] = "\t\t\t\t- ";
static char const deepin[] = "\t\t\t\t ";
static char const onetab[] = "\t";
const struct {long const rmin, rmax;} * rng = rng_table;
char const * pz_indent =
(pOpts != OPTPROC_EMIT_USAGE) ? onetab : bullet;
if ((pOpts == OPTPROC_EMIT_USAGE) || (pOpts > OPTPROC_EMIT_LIMIT)) {
char const * lie_in_range = zRangeLie;
if (pOpts > OPTPROC_EMIT_LIMIT) {
fprintf(option_usage_fp, zRangeErr,
pOpts->pzProgName, pOD->pz_Name, pOD->optArg.argString);
fprintf(option_usage_fp, "The %s option:\n", pOD->pz_Name);
lie_in_range = zRangeBadLie;
pz_indent = "";
}
if (pOD->fOptState & OPTST_SCALED_NUM)
fprintf(option_usage_fp, zRangeScaled, pz_indent);
if (rng_ct > 1) {
fprintf(option_usage_fp, lie_in_range, pz_indent);
pz_indent =
(pOpts != OPTPROC_EMIT_USAGE) ? onetab : deepin;
} else {
fprintf(option_usage_fp, zRangeOnly, pz_indent);
pz_indent = onetab + 1; /* empty string */
}
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('\n', option_usage_fp);
break;
}
fputs(zRangeOr, option_usage_fp);
rng++;
pz_indent =
(pOpts != OPTPROC_EMIT_USAGE) ? onetab : deepin;
}
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 '\0': 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);
pOD->optArg.argInt = ~0;
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/numeric.c */

582
libopts/parse-duration.c Normal file
View File

@@ -0,0 +1,582 @@
/* Parse a time duration and return a seconds count
Copyright (C) 2008 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>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parse-duration.h"
#ifndef _
#define _(_s) _s
#endif
#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
static unsigned long inline
str_const_to_ul (cch_t * str, cch_t ** ppz, int base)
{
return strtoul (str, (char **)ppz, base);
}
static long inline
str_const_to_l (cch_t * str, cch_t ** ppz, int base)
{
return strtol (str, (char **)ppz, base);
}
static time_t inline
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;
}
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;
}
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);
}
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);
ps = strchr (++pz, '-');
if (ps == NULL)
{
errno = EINVAL;
return BAD_TIME;
}
res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH);
pz++;
ps = pz + strlen (pz);
return parse_scaled_value (res, &pz, ps, SEC_PER_DAY);
}
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);
}
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;
}
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);
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);
}
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);
}
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;
}
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;
}
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 * pz = xstrdup (in_pz);
char * pT = strchr (pz, 'T');
char * ps;
void * fptr = pz;
time_t res = 0;
if (pT != NUL)
{
*(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);
while (isspace ((unsigned char)*++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)
{
time_t res = 0;
while (isspace ((unsigned char)*pz)) pz++;
do {
if (*pz == 'P')
{
res = parse_period (pz + 1);
if ((errno != 0) || (res == BAD_TIME))
break;
return res;
}
if (*pz == 'T')
{
res = parse_time (pz + 1);
if ((errno != 0) || (res == BAD_TIME))
break;
return res;
}
if (! isdigit ((unsigned char)*pz))
break;
res = parse_non_iso8601 (pz);
if ((errno == 0) && (res != BAD_TIME))
return res;
} while (0);
fprintf (stderr, _("Invalid time duration: %s\n"), pz);
if (errno == 0)
errno = EINVAL;
return BAD_TIME;
}
/*
* Local Variables:
* mode: C
* c-file-style: "gnu"
* indent-tabs-mode: nil
* End:
* end of parse-duration.c */

82
libopts/parse-duration.h Normal file
View File

@@ -0,0 +1,82 @@
/* Parse a time duration and return a seconds count
Copyright (C) 2008 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 d NNN h NNN m NNN s
This represents NNN days, NNN hours, NNN minutes and NNN seconds.
The embeded white space is optional.
These terms must appear in this order.
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, 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>
#define BAD_TIME ((time_t)~0)
extern time_t parse_duration(char const * in_pz);
#endif /* GNULIB_PARSE_DURATION_H */

140
libopts/pgusage.c Normal file
View File

@@ -0,0 +1,140 @@
/*
* $Id: pgusage.c,v 4.18 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-07-27 21:08:42 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-2009 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
*/
tePagerState pagerState = PAGER_STATE_INITIAL;
/*=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.
=*/
void
optionPagedUsage( tOptions* pOptions, tOptDesc* pOD )
{
#if defined(__windows__) && !defined(__CYGWIN__)
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();
#ifdef HAVE_SNPRINTF
snprintf(zPageUsage, sizeof(zPageUsage), "/tmp/use.%lu", (tAoUL)my_pid);
#else
sprintf( zPageUsage, "/tmp/use.%lu", (tAoUL)my_pid );
#endif
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:
{
tSCC zPage[] = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu";
tCC* pzPager = (tCC*)getenv( "PAGER" );
/*
* Use the "more(1)" program if "PAGER" has not been defined
*/
if (pzPager == NULL)
pzPager = "more";
/*
* Page the file and remove it when done.
*/
#ifdef HAVE_SNPRINTF
snprintf(zPageUsage, sizeof(zPageUsage), zPage, pzPager, (tAoUL)my_pid);
#else
sprintf( zPageUsage, zPage, pzPager, (tAoUL)my_pid );
#endif
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 */

112
libopts/proto.h Normal file
View File

@@ -0,0 +1,112 @@
/* -*- buffer-read-only: t -*- vi: set ro:
*
* Prototypes for autoopts
* Generated Sat Aug 8 10:14:45 PDT 2009
*/
#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 void
ao_free( void *p );
LOCAL char *
ao_strdup( char const *str );
LOCAL tSuccess
handleOption( tOptions* pOpts, tOptState* pOptState );
LOCAL tSuccess
longOptionFind( tOptions* pOpts, char* pzOptName, tOptState* pOptState );
LOCAL tSuccess
shortOptionFind( tOptions* pOpts, uint_t optValue, tOptState* pOptState );
LOCAL tSuccess
doImmediateOpts( tOptions* pOpts );
LOCAL tSuccess
doRegularOpts( tOptions* pOpts );
/*
* Extracted from configfile.c
*/
LOCAL void
internalFileLoad( tOptions* pOpts );
LOCAL char*
parseAttributes(
tOptions* pOpts,
char* pzText,
tOptionLoadMode* pMode,
tOptionValue* pType );
LOCAL tSuccess
validateOptionsStruct( tOptions* pOpts, char const* pzProgram );
/*
* Extracted from environment.c
*/
LOCAL void
doPrognameEnv( tOptions* pOpts, teEnvPresetType type );
LOCAL void
doEnvPresets( tOptions* pOpts, teEnvPresetType type );
/*
* 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 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 );
#ifdef REDEF_LOCAL
# undef LOCAL
# define LOCAL
#endif
#endif /* AUTOOPTS_PROTO_H_GUARD */

320
libopts/putshell.c Normal file
View File

@@ -0,0 +1,320 @@
/*
* $Id: putshell.c,v 4.27 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-07-27 12:14:38 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-2009 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 forward declarations maintained by mk-fwd */
static void
putQuotedStr( tCC* pzStr );
/* = = = 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
putQuotedStr( tCC* pzStr )
{
/*
* Handle empty strings to make the rest of the logic simpler.
*/
if ((pzStr == NULL) || (*pzStr == NUL)) {
fputs( "''", 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( "\\'", stdout );
pzStr++;
}
if (*pzStr == NUL)
return;
/*
* Start the single quote string
*/
fputc( '\'', stdout );
for (;;) {
tCC* 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 );
}
/*=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;
tSCC zOptCtFmt[] = "OPTION_CT=%d\nexport OPTION_CT\n";
tSCC zOptNumFmt[] = "%1$s_%2$s=%3$d # 0x%3$X\nexport %1$s_%2$s\n";
tSCC zOptDisabl[] = "%1$s_%2$s=%3$s\nexport %1$s_%2$s\n";
tSCC zOptValFmt[] = "%s_%s=";
tSCC zOptEnd[] = "\nexport %s_%s\n";
tSCC zFullOptFmt[]= "%1$s_%2$s='%3$s'\nexport %1$s_%2$s\n";
tSCC zEquivMode[] = "%1$s_%2$s_MODE='%3$s'\nexport %1$s_%2$s_MODE\n";
printf( zOptCtFmt, pOpts->curOptIdx-1 );
do {
tOptDesc* pOD = pOpts->pOptDesc + optIx;
if (SKIP_OPT(pOD))
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) {
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 );
while (IS_PLUS_N_SPACE_CHAR(*pz)) 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( "=%1$lu # 0x%1$lX\n", (unsigned long)val );
val <<= 1;
}
AGFREE(pOD->optArg.argString);
pOD->optArg.argString = NULL;
pOD->fOptState &= ~OPTST_ALLOC_ARG;
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) ) {
tSCC zOptCookieCt[] = "%1$s_%2$s_CT=%3$d\nexport %1$s_%2$s_CT\n";
tArgList* pAL = (tArgList*)pOD->optCookie;
tCC** ppz = pAL->apzArgs;
int ct = pAL->useCt;
printf( zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct );
while (--ct >= 0) {
tSCC numarg_z[] = "%s_%s_%d=";
tSCC end_z[] = "\nexport %s_%s_%d\n";
printf( numarg_z, pOpts->pzPROGNAME, pOD->pz_NAME,
pAL->useCt - ct );
putQuotedStr( *(ppz++) );
printf( end_z, pOpts->pzPROGNAME, pOD->pz_NAME,
pAL->useCt - ct );
}
}
/*
* If the argument has been disabled,
* Then set its value to the disablement string
*/
else if ((pOD->fOptState & OPTST_DISABLED) != 0)
printf( zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
(pOD->pz_DisablePfx != NULL)
? pOD->pz_DisablePfx : "false" );
/*
* If the argument type is numeric, the last arg pointer
* is really the VALUE of the string that was pointed to.
*/
else if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC)
printf( zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
(int)pOD->optArg.argInt );
/*
* 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.
*/
else if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
uintptr_t e_val = pOD->optArg.argEnum;
printf( zOptValFmt, pOpts->pzPROGNAME, pOD->pz_NAME );
/*
* Convert value to string, print that and restore numeric value.
*/
(*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
printf("'%s'", pOD->optArg.argString);
if (pOD->fOptState & OPTST_ALLOC_ARG)
AGFREE(pOD->optArg.argString);
pOD->optArg.argEnum = e_val;
printf(zOptEnd, pOpts->pzPROGNAME, pOD->pz_NAME);
}
/*
* If the argument type is numeric, the last arg pointer
* is really the VALUE of the string that was pointed to.
*/
else if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN)
printf( zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
(pOD->optArg.argBool == 0) ? "false" : "true" );
/*
* IF the option has an empty value,
* THEN we set the argument to the occurrence count.
*/
else if ( (pOD->optArg.argString == NULL)
|| (pOD->optArg.argString[0] == NUL) )
printf( zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
pOD->optOccCt );
/*
* This option has a text value
*/
else {
printf( zOptValFmt, pOpts->pzPROGNAME, pOD->pz_NAME );
putQuotedStr( pOD->optArg.argString );
printf( zOptEnd, pOpts->pzPROGNAME, pOD->pz_NAME );
}
} while (++optIx < pOpts->presetOptCt );
if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
&& (pOpts->curOptIdx < pOpts->origArgCt)) {
fputs( "set --", stdout );
for (optIx = pOpts->curOptIdx; optIx < pOpts->origArgCt; optIx++) {
char* pzArg = pOpts->origArgVect[ optIx ];
if (strchr( pzArg, '\'' ) == NULL)
printf( " '%s'", pzArg );
else {
fputs( " '", stdout );
for (;;) {
char ch = *(pzArg++);
switch (ch) {
case '\'': fputs( "'\\''", stdout ); break;
case NUL: goto arg_done;
default: fputc( ch, stdout ); break;
}
} arg_done:;
fputc( '\'', stdout );
}
}
fputs( "\nOPTION_CT=0\n", stdout );
}
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/putshell.c */

128
libopts/reset.c Normal file
View File

@@ -0,0 +1,128 @@
/*
* $Id: reset.c,v 4.7 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-08-02 12:25:18 bkorb"
*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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 ag_bool reset_active = AG_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);
}
reset_active = AG_TRUE;
if (pzArg[1] == NUL) {
if (*pzArg == '*') {
optionResetEverything(pOpts);
reset_active = AG_FALSE;
return;
}
succ = shortOptionFind(pOpts, (tAoUC)*pzArg, &opt_state);
if (! SUCCESSFUL(succ)) {
fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg);
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
}
} else {
succ = longOptionFind(pOpts, (char *)pzArg, &opt_state);
if (! SUCCESSFUL(succ)) {
fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg);
pOpts->pUsageProc(pOpts, EXIT_FAILURE);
}
}
/*
* 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 = AG_FALSE;
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/reset.c */

227
libopts/restore.c Normal file
View File

@@ -0,0 +1,227 @@
/*
* restore.c $Id: restore.c,v 4.14 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2007-07-04 11:34:40 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-2009 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)
unloadNestedArglist(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 */

791
libopts/save.c Normal file
View File

@@ -0,0 +1,791 @@
/*
* save.c $Id: save.c,v 4.36 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2009-07-20 20:40:28 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-2009 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 zWarn[] = "%s WARNING: cannot save options - ";
static char const close_xml[] = "</%s>\n";
/* = = = START-STATIC-FORWARD = = = */
/* static forward declarations maintained by mk-fwd */
static tCC*
findDirName( tOptions* pOpts, int* p_free );
static tCC*
findFileName( tOptions* pOpts, int* p_free_name );
static void
printEntry(
FILE * fp,
tOptDesc * p,
tCC* pzLA );
static void
print_a_value(FILE * fp, int depth, tOptDesc * pOD, tOptionValue const * ovp);
static void
print_a_string(FILE * fp, char const * name, char const * pz);
static void
printValueList(FILE * fp, char const * name, tArgList * al);
static void
printHierarchy(FILE * fp, tOptDesc * p);
static FILE *
openSaveFile( tOptions* pOpts );
static void
printNoArgOpt(FILE * fp, tOptDesc * p, tOptDesc * pOD);
static void
printStringArg(FILE * fp, tOptDesc * pOD);
static void
printEnumArg(FILE * fp, tOptDesc * pOD);
static void
printSetMemberArg(FILE * fp, tOptDesc * pOD);
static void
printFileArg(FILE * fp, tOptDesc * pOD, tOptions* pOpts);
/* = = = END-STATIC-FORWARD = = = */
static tCC*
findDirName( tOptions* pOpts, int* p_free )
{
tCC* 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.
*/
{
tCC* 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;
{
tCC* pzEndDir = strchr( ++pzDir, DIRCH );
char* pzFileName;
char* pzEnv;
if (pzEndDir != NULL) {
char z[ AO_NAME_SIZE ];
if ((pzEndDir - pzDir) > AO_NAME_LIMIT )
return NULL;
strncpy( 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, zWarn, 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 tCC*
findFileName( tOptions* pOpts, int* p_free_name )
{
tCC* pzDir;
struct stat stBuf;
int free_dir_name = 0;
pzDir = findDirName( 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 {
/*
* 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) {
char z[AG_PATH_MAX];
/*
* Strip off the last component, stat the remaining string and
* that string must name a directory
*/
char* pzDirCh = strrchr( pzDir, DIRCH );
if (pzDirCh == NULL) {
stBuf.st_mode = S_IFREG;
continue; /* bail out of error condition */
}
strncpy( z, pzDir, (size_t)(pzDirCh - pzDir));
z[ pzDirCh - pzDir ] = NUL;
if ( (stat( z, &stBuf ) == 0)
&& S_ISDIR( stBuf.st_mode )) {
/*
* We found the directory. Restore the file name and
* mark the full name as a regular file
*/
stBuf.st_mode = S_IFREG;
continue; /* bail out of error condition */
}
}
/*
* We got a bogus name.
*/
fprintf( stderr, zWarn, pOpts->pzProgName );
fprintf( stderr, zNoStat, errno, strerror( errno ), pzDir );
if (free_dir_name)
AGFREE( (void*)pzDir );
return NULL;
} while (0);
/*
* 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, zWarn, 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, zWarn, 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
printEntry(
FILE * fp,
tOptDesc * p,
tCC* 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( '\n', fp );
else {
fputc( ' ', fp ); fputc( ' ', fp );
for (;;) {
tCC* pzNl = strchr( pzLA, '\n' );
/*
* 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( '\n', fp );
}
}
static void
print_a_value(FILE * fp, int depth, tOptDesc * pOD, tOptionValue const * ovp)
{
static char const bool_atr[] = "<%1$s type=boolean>%2$s</%1$s>\n";
static char const numb_atr[] = "<%1$s type=integer>0x%2$lX</%1$s>\n";
static char const type_atr[] = "<%s type=%s>";
static char const null_atr[] = "<%s/>\n";
while (--depth >= 0)
putc(' ', fp), putc(' ', fp);
switch (ovp->valType) {
default:
case OPARG_TYPE_NONE:
fprintf(fp, null_atr, ovp->pzName);
break;
case OPARG_TYPE_STRING:
print_a_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, 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, close_xml, ovp->pzName);
break;
}
/* FALLTHROUGH */
case OPARG_TYPE_NUMERIC:
fprintf(fp, numb_atr, ovp->pzName, ovp->v.longVal);
break;
case OPARG_TYPE_BOOLEAN:
fprintf(fp, bool_atr, ovp->pzName,
ovp->v.boolVal ? "true" : "false");
break;
case OPARG_TYPE_HIERARCHY:
printValueList(fp, ovp->pzName, ovp->v.nestVal);
break;
}
}
static void
print_a_string(FILE * fp, char const * name, char const * pz)
{
static char const open_atr[] = "<%s>";
fprintf(fp, open_atr, 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, close_xml, name);
}
static void
printValueList(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, "<%s/>\n", name);
return;
}
fprintf(fp, "<%s type=nested>\n", name);
depth++;
while (--opt_ct >= 0) {
tOptionValue const * ovp = *(opt_list++);
print_a_value(fp, depth, NULL, ovp);
}
depth--;
for (sp_ct = depth; --sp_ct >= 0;)
putc(' ', fp), putc(' ', fp);
fprintf(fp, "</%s>\n", name);
}
static void
printHierarchy(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, "<%s type=nested>\n", p->pz_Name);
do {
print_a_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 *
openSaveFile( tOptions* pOpts )
{
FILE* fp;
{
int free_name = 0;
tCC* pzFName = findFileName( pOpts, &free_name );
if (pzFName == NULL)
return NULL;
fp = fopen( pzFName, "w" FOPEN_BINARY_FLAG );
if (fp == NULL) {
fprintf( stderr, zWarn, 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++) != '\n');
}
{
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
printNoArgOpt(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
printStringArg(FILE * fp, tOptDesc * pOD)
{
if (pOD->fOptState & OPTST_STACKED) {
tArgList* pAL = (tArgList*)pOD->optCookie;
int uct = pAL->useCt;
tCC** ppz = pAL->apzArgs;
/*
* un-disable multiple copies of disabled options.
*/
if (uct > 1)
pOD->fOptState &= ~OPTST_DISABLED;
while (uct-- > 0)
printEntry( fp, pOD, *(ppz++) );
} else {
printEntry( fp, pOD, pOD->optArg.argString );
}
}
static void
printEnumArg(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);
printEntry( fp, pOD, (void*)(pOD->optArg.argString));
pOD->optArg.argEnum = val;
}
static void
printSetMemberArg(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);
printEntry( 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
printFileArg(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)
printEntry(fp, pOD, pOD->optCookie);
else if (HAS_originalOptArgArray(pOpts)) {
char const * orig =
pOpts->originalOptArgArray[pOD->optIndex].argString;
if (pOD->optArg.argString == orig)
return;
printEntry(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 = openSaveFile(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:
printNoArgOpt(fp, p, pOD);
break;
case OPARG_TYPE_NUMERIC:
printEntry( fp, p, (void*)(p->optArg.argInt));
break;
case OPARG_TYPE_STRING:
printStringArg(fp, p);
break;
case OPARG_TYPE_ENUMERATION:
printEnumArg(fp, p);
break;
case OPARG_TYPE_MEMBERSHIP:
printSetMemberArg(fp, p);
break;
case OPARG_TYPE_BOOLEAN:
printEntry( fp, p, p->optArg.argBool ? "true" : "false" );
break;
case OPARG_TYPE_HIERARCHY:
printHierarchy(fp, p);
break;
case OPARG_TYPE_FILE:
printFileArg(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
libopts/sort.c Normal file
View File

@@ -0,0 +1,336 @@
/*
* sort.c $Id: sort.c,v 4.17 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2007-07-04 11:34:52 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-2009 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 forward declarations maintained by mk-fwd */
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( shortOptionFind( 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 = longOptionFind( 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 = longOptionFind( pOpts, pzArg+1, &os );
} else {
res = shortOptionFind( 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
libopts/stack.c Normal file
View File

@@ -0,0 +1,264 @@
/*
* stack.c
* $Id: stack.c,v 4.19 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-07-30 16:56:32 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-2009 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 )
{
int res;
tArgList* pAL;
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++) {
tCC* pzSrc = pAL->apzArgs[ i ];
char* pzEq = strchr( pzSrc, '=' );
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;
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 */

266
libopts/streqvcmp.c Normal file
View File

@@ -0,0 +1,266 @@
/*
* $Id: streqvcmp.c,v 4.17 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-12-26 10:15:46 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-2009 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[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a',
'\b', '\t', '\n', '\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 ] = ct;
} while (--ct >= 0);
}
else {
int chTo = (int)To & 0xFF;
int chFrom = (int)From & 0xFF;
do {
charmap[ chFrom ] = (unsigned)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 */

383
libopts/text_mmap.c Normal file
View File

@@ -0,0 +1,383 @@
/*
* $Id: text_mmap.c,v 4.21 2009/08/01 17:43:06 bkorb Exp $
*
* Time-stamp: "2007-07-04 11:35:49 bkorb"
*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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 MAP_ANONYMOUS
# ifdef MAP_ANON
# define MAP_ANONYMOUS MAP_ANON
# 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)
/*=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 @file{errno}
* appropriately.
*
* The named file does not exist, @code{stat(2)} will set @file{errno} as it
* will. If the file is not a regular file, @file{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, @file{errno} will be set according to the documentation
* for @code{open(2)}. If @code{mmap(2)} fails, @file{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 @file{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* pMI )
{
memset( pMI, 0, sizeof(*pMI) );
#ifdef HAVE_MMAP
pMI->txt_zero_fd = -1;
#endif
pMI->txt_fd = -1;
/*
* Make sure we can stat the regular file. Save the file size.
*/
{
struct stat sb;
if (stat( pzFile, &sb ) != 0) {
pMI->txt_errno = errno;
return MAP_FAILED_PTR;
}
if (! S_ISREG( sb.st_mode )) {
pMI->txt_errno = errno = EINVAL;
return MAP_FAILED_PTR;
}
pMI->txt_size = sb.st_size;
}
/*
* Map mmap flags and protections into open flags and do the open.
*/
{
int o_flag;
/*
* 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.
*/
if (FILE_WRITABLE(prot,flags))
o_flag = O_RDWR;
else
o_flag = 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;
pMI->txt_fd = open( pzFile, o_flag );
}
if (pMI->txt_fd == AO_INVALID_FD) {
pMI->txt_errno = errno;
return MAP_FAILED_PTR;
}
#ifdef HAVE_MMAP /* * * * * WITH MMAP * * * * * */
/*
* do the mmap. If we fail, then preserve errno, close the file and
* return the failure.
*/
pMI->txt_data =
mmap(NULL, pMI->txt_size+1, prot, flags, pMI->txt_fd, (size_t)0);
if (pMI->txt_data == MAP_FAILED_PTR) {
pMI->txt_errno = errno;
goto fail_return;
}
/*
* Most likely, everything will turn out fine now. The only difficult
* part at this point is coping with files with sizes that are a multiple
* of the page size. Handling that is what this whole thing is about.
*/
pMI->txt_zero_fd = -1;
pMI->txt_errno = 0;
{
void* pNuls;
#ifdef _SC_PAGESIZE
size_t pgsz = sysconf(_SC_PAGESIZE);
#else
size_t pgsz = getpagesize();
#endif
/*
* Compute the pagesize rounded mapped memory size.
* IF this is not the same as the file size, then there are NUL's
* at the end of the file mapping and all is okay.
*/
pMI->txt_full_size = (pMI->txt_size + (pgsz - 1)) & ~(pgsz - 1);
if (pMI->txt_size != pMI->txt_full_size)
return pMI->txt_data;
/*
* Still here? We have to remap the trailing inaccessible page
* either anonymously or to /dev/zero.
*/
pMI->txt_full_size += pgsz;
#if defined(MAP_ANONYMOUS)
pNuls = mmap(
(void*)(((char*)pMI->txt_data) + pMI->txt_size),
pgsz, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE, AO_INVALID_FD, (size_t)0);
if (pNuls != MAP_FAILED_PTR)
return pMI->txt_data;
pMI->txt_errno = errno;
#elif defined(HAVE_DEV_ZERO)
pMI->txt_zero_fd = open( "/dev/zero", O_RDONLY );
if (pMI->txt_zero_fd == AO_INVALID_FD) {
pMI->txt_errno = errno;
} else {
pNuls = mmap(
(void*)(((char*)pMI->txt_data) + pMI->txt_size), pgsz,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED,
pMI->txt_zero_fd, 0 );
if (pNuls != MAP_FAILED_PTR)
return pMI->txt_data;
pMI->txt_errno = errno;
close( pMI->txt_zero_fd );
pMI->txt_zero_fd = -1;
}
#endif
pMI->txt_full_size = pMI->txt_size;
}
{
void* p = AGALOC( pMI->txt_size+1, "file text" );
memcpy( p, pMI->txt_data, pMI->txt_size );
((char*)p)[pMI->txt_size] = NUL;
munmap(pMI->txt_data, pMI->txt_size );
pMI->txt_data = p;
}
pMI->txt_alloc = 1;
return pMI->txt_data;
#else /* * * * * * no HAVE_MMAP * * * * * */
pMI->txt_data = AGALOC( pMI->txt_size+1, "file text" );
if (pMI->txt_data == NULL) {
pMI->txt_errno = ENOMEM;
goto fail_return;
}
{
size_t sz = pMI->txt_size;
char* pz = pMI->txt_data;
while (sz > 0) {
ssize_t rdct = read( pMI->txt_fd, pz, sz );
if (rdct <= 0) {
pMI->txt_errno = errno;
fprintf( stderr, zFSErrReadFile,
errno, strerror( errno ), pzFile );
free( pMI->txt_data );
goto fail_return;
}
pz += rdct;
sz -= rdct;
}
*pz = NUL;
}
/*
* We never need a dummy page mapped in
*/
pMI->txt_zero_fd = -1;
pMI->txt_errno = 0;
return pMI->txt_data;
#endif /* * * * * * no HAVE_MMAP * * * * * */
fail_return:
if (pMI->txt_fd >= 0) {
close( pMI->txt_fd );
pMI->txt_fd = -1;
}
errno = pMI->txt_errno;
pMI->txt_data = MAP_FAILED_PTR;
return pMI->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. @file{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* pMI )
{
#ifdef HAVE_MMAP
int res = 0;
if (pMI->txt_alloc) {
/*
* IF the user has write permission and the text is not mapped private,
* then write back any changes. Hopefully, nobody else has modified
* the file in the mean time.
*/
if ( ((pMI->txt_prot & PROT_WRITE) != 0)
&& ((pMI->txt_flags & MAP_PRIVATE) == 0)) {
if (lseek(pMI->txt_fd, (size_t)0, SEEK_SET) != 0)
goto error_return;
res = (write( pMI->txt_fd, pMI->txt_data, pMI->txt_size ) < 0)
? errno : 0;
}
AGFREE( pMI->txt_data );
errno = res;
} else {
res = munmap( pMI->txt_data, pMI->txt_full_size );
}
if (res != 0)
goto error_return;
res = close( pMI->txt_fd );
if (res != 0)
goto error_return;
pMI->txt_fd = -1;
errno = 0;
if (pMI->txt_zero_fd != -1) {
res = close( pMI->txt_zero_fd );
pMI->txt_zero_fd = -1;
}
error_return:
pMI->txt_errno = errno;
return res;
#else /* HAVE_MMAP */
errno = 0;
/*
* 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.
*/
if ( FILE_WRITABLE(pMI->txt_prot, pMI->txt_flags)
&& (lseek( pMI->txt_fd, 0, SEEK_SET ) >= 0) ) {
write( pMI->txt_fd, pMI->txt_data, pMI->txt_size );
}
close( pMI->txt_fd );
pMI->txt_fd = -1;
pMI->txt_errno = errno;
free( pMI->txt_data );
return pMI->txt_errno;
#endif /* HAVE_MMAP */
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/text_mmap.c */

88
libopts/time.c Normal file
View File

@@ -0,0 +1,88 @@
/*
* $Id: time.c,v 4.5 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-11-16 14:51:48 bkorb"
*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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 HAVE_PARSE_DURATION
#include <time.h>
static inline char *
ao_xstrdup(char const * pz)
{
char * str;
AGDUPSTR(str, pz, "time val str");
return str;
}
#define xstrdup(_s) ao_xstrdup(_s)
#include "parse-duration.c"
#undef xstrdup
#endif
/*=export_func optionTimeVal
* private:
*
* what: process an option with a time value.
* 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 )
{
long val;
if ((pOD->fOptState & OPTST_RESET) != 0)
return;
val = parse_duration(pOD->optArg.argString);
if (errno != 0)
goto bad_time;
if (pOD->fOptState & OPTST_ALLOC_ARG) {
AGFREE(pOD->optArg.argString);
pOD->fOptState &= ~OPTST_ALLOC_ARG;
}
pOD->optArg.argInt = val;
return;
bad_time:
fprintf( stderr, zNotNumber, pOpts->pzProgName, pOD->optArg.argString );
if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
(*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
pOD->optArg.argInt = ~0;
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/numeric.c */

323
libopts/tokenize.c Normal file
View File

@@ -0,0 +1,323 @@
/*
* This file defines the string_tokenize interface
* Time-stamp: "2007-11-12 20:40:36 bkorb"
*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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 forward declarations maintained by mk-fwd */
static void
copy_cooked( ch_t** ppDest, char const ** ppSrc );
static void
copy_raw( ch_t** ppDest, char const ** ppSrc );
/* = = = 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) == '\n')
++pSrc;
continue;
case '\n':
++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 */
}
/*=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 )
{
int max_token_ct = 1; /* allow for trailing NUL on string */
token_list_t* res;
if (str == NULL) goto bogus_str;
/*
* Trim leading white space. Use "ENOENT" and a NULL return to indicate
* an empty string was passed.
*/
while (IS_WHITESPACE_CHAR(*str)) str++;
if (*str == NUL) {
bogus_str:
errno = ENOENT;
return NULL;
}
/*
* 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.
*/
{
cc_t* pz = (cc_t*)str;
do {
max_token_ct++;
while (! IS_WHITESPACE_CHAR(*++pz))
if (*pz == NUL) goto found_nul;
while (IS_WHITESPACE_CHAR(*pz)) pz++;
} while (*pz != NUL);
found_nul:
;
}
res = malloc( sizeof(*res) + strlen(str) + (max_token_ct * sizeof(ch_t*)) );
if (res == NULL) {
errno = ENOMEM;
return res;
}
/*
* Now copy each token into the output buffer.
*/
{
ch_t* pzDest = (ch_t*)(res->tkn_list + (max_token_ct + 1));
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:
while (IS_WHITESPACE_CHAR(*++str)) ;
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++) = 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 */

762
libopts/usage.c Normal file
View File

@@ -0,0 +1,762 @@
/*
* usage.c $Id: usage.c,v 4.30 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2009-01-17 13:18:23 bkorb"
*
* This module implements the default usage procedure for
* Automated Options. It may be overridden, of course.
*
* Sort options:
--start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
--out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
--spac=2 --input=usage.c
*/
/*
* This file is part of AutoOpts, a companion to AutoGen.
* AutoOpts is free software.
* AutoOpts is copyright (c) 1992-2009 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
*/
#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
static arg_types_t argTypes;
FILE* option_usage_fp = NULL;
static char zOptFmtLine[ 16 ];
static ag_bool displayEnum;
/* = = = START-STATIC-FORWARD = = = */
/* static forward declarations maintained by mk-fwd */
static ag_bool
checkGNUUsage( tOptions* pOpts );
static void
printExtendedUsage(
tOptions* pOptions,
tOptDesc* pOD,
arg_types_t* pAT );
static void
printInitList(
tCC* const* papz,
ag_bool* pInitIntro,
tCC* pzRc,
tCC* pzPN );
static void
printOneUsage(
tOptions* pOptions,
tOptDesc* pOD,
arg_types_t* pAT );
static void
printOptionUsage(
tOptions* pOpts,
int ex_code,
tCC* pOptTitle );
static void
printProgramDetails( tOptions* pOptions );
static int
setGnuOptFmts( tOptions* pOpts, tCC** ppT );
static int
setStdOptFmts( tOptions* pOpts, tCC** ppT );
/* = = = END-STATIC-FORWARD = = = */
/*
* Figure out if we should try to format usage text sort-of like
* the way many GNU programs do.
*/
static ag_bool
checkGNUUsage( tOptions* pOpts )
{
char* pz = getenv( "AUTOOPTS_USAGE" );
if (pz == NULL)
;
else if (streqvcmp( pz, "gnu" ) == 0)
pOpts->fOptSet |= OPTPROC_GNUUSAGE;
else if (streqvcmp( pz, "autoopts" ) == 0)
pOpts->fOptSet &= ~OPTPROC_GNUUSAGE;
return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? AG_TRUE : AG_FALSE;
}
/*=export_func optionOnlyUsage
*
* what: Print usage text for just the options
* arg: + tOptions* + pOpts + program options descriptor +
* arg: + int + ex_code + exit code for calling exit(3) +
*
* doc:
* This routine will print only the usage for each option.
* This function may be used when the emitted usage must incorporate
* information not available to AutoOpts.
=*/
void
optionOnlyUsage(
tOptions* pOpts,
int ex_code )
{
tCC* pOptTitle = NULL;
/*
* Determine which header and which option formatting strings to use
*/
if (checkGNUUsage(pOpts)) {
(void)setGnuOptFmts( pOpts, &pOptTitle );
}
else {
(void)setStdOptFmts( pOpts, &pOptTitle );
}
printOptionUsage( pOpts, ex_code, pOptTitle );
}
/*=export_func optionUsage
* private:
*
* what: Print usage text
* arg: + tOptions* + pOptions + program options descriptor +
* arg: + int + exitCode + exit code for calling exit(3) +
*
* doc:
* This routine will print usage in both GNU-standard and AutoOpts-expanded
* formats. The descriptor specifies the default, but AUTOOPTS_USAGE will
* over-ride this, providing the value of it is set to either "gnu" or
* "autoopts". This routine will @strong{not} return.
*
* If "exitCode" is "EX_USAGE" (normally 64), then output will to to stdout
* and the actual exit code will be "EXIT_SUCCESS".
=*/
void
optionUsage(
tOptions* pOptions,
int usage_exit_code )
{
int actual_exit_code =
(usage_exit_code == EX_USAGE) ? EXIT_SUCCESS : usage_exit_code;
displayEnum = AG_FALSE;
/*
* Paged usage will preset option_usage_fp to an output file.
* If it hasn't already been set, then set it to standard output
* on successful exit (help was requested), otherwise error out.
*
* Test the version before obtaining pzFullUsage or pzShortUsage.
* These fields do not exist before revision 30.
*/
{
char const * pz;
if (actual_exit_code == EXIT_SUCCESS) {
pz = (pOptions->structVersion >= 30 * 4096)
? pOptions->pzFullUsage : NULL;
if (option_usage_fp == NULL)
option_usage_fp = stdout;
} else {
pz = (pOptions->structVersion >= 30 * 4096)
? pOptions->pzShortUsage : NULL;
if (option_usage_fp == NULL)
option_usage_fp = stderr;
}
if (pz != NULL) {
fputs(pz, option_usage_fp);
exit(actual_exit_code);
}
}
fprintf( option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName );
{
tCC* pOptTitle = NULL;
/*
* Determine which header and which option formatting strings to use
*/
if (checkGNUUsage(pOptions)) {
int flen = setGnuOptFmts( pOptions, &pOptTitle );
sprintf( zOptFmtLine, zFmtFmt, flen );
fputc( '\n', option_usage_fp );
}
else {
int flen = setStdOptFmts( pOptions, &pOptTitle );
sprintf( zOptFmtLine, zFmtFmt, flen );
/*
* When we exit with EXIT_SUCCESS and the first option is a doc
* option, we do *NOT* want to emit the column headers.
* Otherwise, we do.
*/
if ( (usage_exit_code != EXIT_SUCCESS)
|| ((pOptions->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
fputs( pOptTitle, option_usage_fp );
}
printOptionUsage( pOptions, usage_exit_code, pOptTitle );
}
/*
* Describe the mechanics of denoting the options
*/
switch (pOptions->fOptSet & OPTPROC_L_N_S) {
case OPTPROC_L_N_S: fputs( zFlagOkay, option_usage_fp ); break;
case OPTPROC_SHORTOPT: break;
case OPTPROC_LONGOPT: fputs( zNoFlags, option_usage_fp ); break;
case 0: fputs( zOptsOnly, option_usage_fp ); break;
}
if ((pOptions->fOptSet & OPTPROC_NUM_OPT) != 0) {
fputs( zNumberOpt, option_usage_fp );
}
if ((pOptions->fOptSet & OPTPROC_REORDER) != 0) {
fputs( zReorder, option_usage_fp );
}
if (pOptions->pzExplain != NULL)
fputs( pOptions->pzExplain, option_usage_fp );
/*
* IF the user is asking for help (thus exiting with SUCCESS),
* THEN see what additional information we can provide.
*/
if (usage_exit_code == EXIT_SUCCESS)
printProgramDetails( pOptions );
if (pOptions->pzBugAddr != NULL)
fprintf( option_usage_fp, zPlsSendBugs, pOptions->pzBugAddr );
fflush( option_usage_fp );
exit( actual_exit_code );
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* PER OPTION TYPE USAGE INFORMATION
*/
static void
printExtendedUsage(
tOptions* pOptions,
tOptDesc* pOD,
arg_types_t* pAT )
{
/*
* IF there are option conflicts or dependencies,
* THEN print them here.
*/
if ( (pOD->pOptMust != NULL)
|| (pOD->pOptCant != NULL) ) {
fputs( zTabHyp, option_usage_fp );
/*
* DEPENDENCIES:
*/
if (pOD->pOptMust != NULL) {
const int* pOptNo = pOD->pOptMust;
fputs( zReqThese, option_usage_fp );
for (;;) {
fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
*pOptNo ].pz_Name );
if (*++pOptNo == NO_EQUIVALENT)
break;
}
if (pOD->pOptCant != NULL)
fputs( zTabHypAnd, option_usage_fp );
}
/*
* CONFLICTS:
*/
if (pOD->pOptCant != NULL) {
const int* pOptNo = pOD->pOptCant;
fputs( zProhib, option_usage_fp );
for (;;) {
fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
*pOptNo ].pz_Name );
if (*++pOptNo == NO_EQUIVALENT)
break;
}
}
}
/*
* IF there is a disablement string
* THEN print the disablement info
*/
if (pOD->pz_DisableName != NULL )
fprintf( option_usage_fp, zDis, pOD->pz_DisableName );
/*
* Check for argument types that have callbacks with magical properties
*/
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
case OPARG_TYPE_NUMERIC:
/*
* IF the numeric option has a special callback,
* THEN call it, requesting the range or other special info
*/
if ( (pOD->pOptProc != NULL)
&& (pOD->pOptProc != optionNumericVal) ) {
(*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
}
break;
case OPARG_TYPE_FILE:
(*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
break;
}
/*
* IF the option defaults to being enabled,
* THEN print that out
*/
if (pOD->fOptState & OPTST_INITENABLED)
fputs( zEnab, option_usage_fp );
/*
* IF the option is in an equivalence class
* AND not the designated lead
* THEN print equivalence and leave it at that.
*/
if ( (pOD->optEquivIndex != NO_EQUIVALENT)
&& (pOD->optEquivIndex != pOD->optActualIndex ) ) {
fprintf( option_usage_fp, zAlt,
pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name );
return;
}
/*
* IF this particular option can NOT be preset
* AND some form of presetting IS allowed,
* AND it is not an auto-managed option (e.g. --help, et al.)
* THEN advise that this option may not be preset.
*/
if ( ((pOD->fOptState & OPTST_NO_INIT) != 0)
&& ( (pOptions->papzHomeList != NULL)
|| (pOptions->pzPROGNAME != NULL)
)
&& (pOD->optIndex < pOptions->presetOptCt)
)
fputs( zNoPreset, option_usage_fp );
/*
* Print the appearance requirements.
*/
if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP)
fputs( zMembers, option_usage_fp );
else switch (pOD->optMinCt) {
case 1:
case 0:
switch (pOD->optMaxCt) {
case 0: fputs( zPreset, option_usage_fp ); break;
case NOLIMIT: fputs( zNoLim, option_usage_fp ); break;
case 1: break;
/*
* IF the max is more than one but limited, print "UP TO" message
*/
default: fprintf( option_usage_fp, zUpTo, pOD->optMaxCt ); break;
}
break;
default:
/*
* More than one is required. Print the range.
*/
fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt );
}
if ( NAMED_OPTS( pOptions )
&& (pOptions->specOptIdx.default_opt == pOD->optIndex))
fputs( zDefaultOpt, option_usage_fp );
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Figure out where all the initialization files might live.
* This requires translating some environment variables and
* testing to see if a name is a directory or a file. It's
* squishy, but important to tell users how to find these files.
*/
static void
printInitList(
tCC* const* papz,
ag_bool* pInitIntro,
tCC* pzRc,
tCC* pzPN )
{
char zPath[ AG_PATH_MAX+1 ];
if (papz == NULL)
return;
fputs( zPresetIntro, option_usage_fp );
*pInitIntro = AG_FALSE;
for (;;) {
char const* pzPath = *(papz++);
if (pzPath == NULL)
break;
if (optionMakePath(zPath, (int)sizeof( zPath ), pzPath, pzPN))
pzPath = zPath;
/*
* Print the name of the "homerc" file. If the "rcfile" name is
* not empty, we may or may not print that, too...
*/
fprintf( option_usage_fp, zPathFmt, pzPath );
if (*pzRc != NUL) {
struct stat sb;
/*
* IF the "homerc" file is a directory,
* then append the "rcfile" name.
*/
if ( (stat( pzPath, &sb ) == 0)
&& S_ISDIR( sb.st_mode ) ) {
fputc( DIRCH, option_usage_fp );
fputs( pzRc, option_usage_fp );
}
}
fputc( '\n', option_usage_fp );
}
}
/*
* Print the usage information for a single option.
*/
static void
printOneUsage(
tOptions* pOptions,
tOptDesc* pOD,
arg_types_t* pAT )
{
/*
* Flag prefix: IF no flags at all, then omit it. If not printable
* (not allowed for this option), then blank, else print it.
* Follow it with a comma if we are doing GNU usage and long
* opts are to be printed too.
*/
#ifdef TCPBURST
if(30 == pOD->optIndex) /* <20><><EFBFBD><EFBFBD>׼tcpreplay<61><79><EFBFBD><EFBFBD><EFBFBD>ָ */
{
fprintf(option_usage_fp, "\n ========================== 2013-06-06 New Arguments For Tcpburst ===============\n");
}
#endif
if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0)
fputs( pAT->pzSpc, option_usage_fp );
else if (! IS_GRAPHIC_CHAR(pOD->optValue)) {
if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
== (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
fputc( ' ', option_usage_fp );
fputs( pAT->pzNoF, option_usage_fp );
} else {
fprintf( option_usage_fp, " -%c", pOD->optValue );
if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
== (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
fputs( ", ", option_usage_fp );
}
{
char z[ 80 ];
tCC* pzArgType;
/*
* Determine the argument type string first on its usage, then,
* when the option argument is required, base the type string on the
* argument type.
*/
if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
pzArgType = pAT->pzOpt;
} else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
case OPARG_TYPE_NONE: pzArgType = pAT->pzNo; break;
case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break;
case OPARG_TYPE_FILE : pzArgType = pAT->pzFile; break;
case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break;
case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break;
case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break;
case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break;
case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break;
case OPARG_TYPE_TIME: pzArgType = pAT->pzTime; break;
default: goto bogus_desc;
}
snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
(pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt );
fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText );
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
case OPARG_TYPE_ENUMERATION:
case OPARG_TYPE_MEMBERSHIP:
displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum;
}
}
return;
bogus_desc:
fprintf( stderr, zInvalOptDesc, pOD->pz_Name );
exit( EX_SOFTWARE );
}
/*
* Print out the usage information for just the options.
*/
static void
printOptionUsage(
tOptions* pOpts,
int ex_code,
tCC* pOptTitle )
{
int ct = pOpts->optCt;
int optNo = 0;
tOptDesc* pOD = pOpts->pOptDesc;
int docCt = 0;
do {
if ((pOD->fOptState & OPTST_NO_USAGE_MASK) != 0)
continue;
if ((pOD->fOptState & OPTST_DOCUMENT) != 0) {
if (ex_code == EXIT_SUCCESS) {
fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText,
pOptTitle);
docCt++;
}
continue;
}
/*
* IF this is the first auto-opt maintained option
* *AND* we are doing a full help
* *AND* there are documentation options
* *AND* the last one was not a doc option,
* THEN document that the remaining options are not user opts
*/
if ( (pOpts->presetOptCt == optNo)
&& (ex_code == EXIT_SUCCESS)
&& (docCt > 0)
&& ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) )
fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle );
printOneUsage( pOpts, pOD, &argTypes );
/*
* IF we were invoked because of the --help option,
* THEN print all the extra info
*/
if (ex_code == EXIT_SUCCESS)
printExtendedUsage( pOpts, pOD, &argTypes );
} while (pOD++, optNo++, (--ct > 0));
fputc( '\n', option_usage_fp );
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* PROGRAM DETAILS
*/
static void
printProgramDetails( tOptions* pOptions )
{
ag_bool initIntro = AG_TRUE;
/*
* Display all the places we look for config files
*/
printInitList( pOptions->papzHomeList, &initIntro,
pOptions->pzRcName, pOptions->pzProgPath );
/*
* Let the user know about environment variable settings
*/
if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) {
if (initIntro)
fputs( zPresetIntro, option_usage_fp );
fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME );
}
/*
* IF we found an enumeration,
* THEN hunt for it again. Call the handler proc with a NULL
* option struct pointer. That tells it to display the keywords.
*/
if (displayEnum) {
int ct = pOptions->optCt;
int optNo = 0;
tOptDesc* pOD = pOptions->pOptDesc;
fputc( '\n', option_usage_fp );
fflush( option_usage_fp );
do {
switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
case OPARG_TYPE_ENUMERATION:
case OPARG_TYPE_MEMBERSHIP:
(*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
}
} while (pOD++, optNo++, (--ct > 0));
}
/*
* If there is a detail string, now is the time for that.
*/
if (pOptions->pzDetail != NULL)
fputs( pOptions->pzDetail, option_usage_fp );
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* OPTION LINE FORMATTING SETUP
*
* The "OptFmt" formats receive three arguments:
* 1. the type of the option's argument
* 2. the long name of the option
* 3. "YES" or "no ", depending on whether or not the option must appear
* on the command line.
* These formats are used immediately after the option flag (if used) has
* been printed.
*
* Set up the formatting for GNU-style output
*/
static int
setGnuOptFmts( tOptions* pOpts, tCC** ppT )
{
int flen = 22;
*ppT = zNoRq_ShrtTtl;
argTypes.pzStr = zGnuStrArg;
argTypes.pzReq = zOneSpace;
argTypes.pzNum = zGnuNumArg;
argTypes.pzKey = zGnuKeyArg;
argTypes.pzKeyL = zGnuKeyLArg;
argTypes.pzTime = zGnuTimeArg;
argTypes.pzFile = zGnuFileArg;
argTypes.pzBool = zGnuBoolArg;
argTypes.pzNest = zGnuNestArg;
argTypes.pzOpt = zGnuOptArg;
argTypes.pzNo = zOneSpace;
argTypes.pzBrk = zGnuBreak;
argTypes.pzNoF = zSixSpaces;
argTypes.pzSpc = zThreeSpaces;
switch (pOpts->fOptSet & OPTPROC_L_N_S) {
case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break;
case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break;
case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break;
case OPTPROC_SHORTOPT:
argTypes.pzOptFmt = zShrtGnuOptFmt;
zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' ';
argTypes.pzOpt = " [arg]";
flen = 8;
break;
}
return flen;
}
/*
* Standard (AutoOpts normal) option line formatting
*/
static int
setStdOptFmts( tOptions* pOpts, tCC** ppT )
{
int flen = 0;
argTypes.pzStr = zStdStrArg;
argTypes.pzReq = zStdReqArg;
argTypes.pzNum = zStdNumArg;
argTypes.pzKey = zStdKeyArg;
argTypes.pzKeyL = zStdKeyLArg;
argTypes.pzTime = zStdTimeArg;
argTypes.pzFile = zStdFileArg;
argTypes.pzBool = zStdBoolArg;
argTypes.pzNest = zStdNestArg;
argTypes.pzOpt = zStdOptArg;
argTypes.pzNo = zStdNoArg;
argTypes.pzBrk = zStdBreak;
argTypes.pzNoF = zFiveSpaces;
argTypes.pzSpc = zTwoSpaces;
switch (pOpts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
*ppT = zNoRq_ShrtTtl;
argTypes.pzOptFmt = zNrmOptFmt;
flen = 19;
break;
case OPTPROC_NO_REQ_OPT:
*ppT = zNoRq_NoShrtTtl;
argTypes.pzOptFmt = zNrmOptFmt;
flen = 19;
break;
case OPTPROC_SHORTOPT:
*ppT = zReq_ShrtTtl;
argTypes.pzOptFmt = zReqOptFmt;
flen = 24;
break;
case 0:
*ppT = zReq_NoShrtTtl;
argTypes.pzOptFmt = zReqOptFmt;
flen = 24;
}
return flen;
}
/*:
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/usage.c */

120
libopts/value-type.c Normal file
View File

@@ -0,0 +1,120 @@
/* ANSI-C code produced by gperf version 3.0.2 */
#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__
#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
libopts/value-type.h Normal file
View File

@@ -0,0 +1,25 @@
/*
* Generated header for gperf generated source Sat Aug 8 10:14:55 PDT 2009
* 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 */

157
libopts/version.c Normal file
View File

@@ -0,0 +1,157 @@
/* $Id: version.c,v 4.19 2009/08/01 17:43:06 bkorb Exp $
* Time-stamp: "2008-07-27 10:11:30 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-2009 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 forward declarations maintained by mk-fwd */
static void
printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp );
/* = = = END-STATIC-FORWARD = = = */
/*=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;
}
static void
printVersion( tOptions* pOpts, tOptDesc* pOD, FILE* fp )
{
char swCh;
/*
* IF the optional argument flag is off, or the argument is not provided,
* then just print the version.
*/
if ( ((pOD->fOptState & OPTST_ARG_OPTIONAL) == 0)
|| (pOD->optArg.argString == NULL))
swCh = 'v';
else swCh = tolower(pOD->optArg.argString[0]);
if (pOpts->pzFullVersion != NULL) {
fputs( pOpts->pzFullVersion, fp );
fputc( '\n', fp );
} else {
char const *pz = pOpts->pzUsageTitle;
do { fputc(*pz, fp); } while (*(pz++) != '\n');
}
switch (swCh) {
case NUL: /* arg provided, but empty */
case 'v':
break;
case 'c':
if (pOpts->pzCopyright != NULL) {
fputs( pOpts->pzCopyright, fp );
fputc( '\n', fp );
}
fprintf( fp, zAO_Ver, optionVersion() );
if (pOpts->pzBugAddr != NULL)
fprintf( fp, zPlsSendBugs, pOpts->pzBugAddr );
break;
case 'n':
if (pOpts->pzCopyright != NULL) {
fputs( pOpts->pzCopyright, fp );
fputc( '\n', fp );
fputc( '\n', fp );
}
if (pOpts->pzCopyNotice != NULL) {
fputs( pOpts->pzCopyNotice, fp );
fputc( '\n', fp );
}
fprintf( fp, zAO_Ver, optionVersion() );
if (pOpts->pzBugAddr != NULL)
fprintf( fp, zPlsSendBugs, pOpts->pzBugAddr );
break;
default:
fprintf( stderr, zBadVerArg, swCh );
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 )
{
printVersion( 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 )
{
printVersion( pOpts, pOD, stderr );
}
/*
* Local Variables:
* mode: C
* c-file-style: "stroustrup"
* indent-tabs-mode: nil
* End:
* end of autoopts/version.c */

111
libopts/xat-attribute.c Normal file
View File

@@ -0,0 +1,111 @@
/* ANSI-C code produced by gperf version 3.0.2 */
#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__
#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
libopts/xat-attribute.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* Generated header for gperf generated source Sat Aug 8 10:14:55 PDT 2009
* 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 */

7357
m4/libtool.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

368
m4/ltoptions.m4 vendored Normal file
View File

@@ -0,0 +1,368 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# 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 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [0], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[pic_mode="$withval"],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

123
m4/ltsugar.m4 vendored Normal file
View File

@@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# 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 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

23
m4/ltversion.m4 vendored Normal file
View File

@@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# 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.
# Generated from ltversion.in.
# serial 3017 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.2.6b])
m4_define([LT_PACKAGE_REVISION], [1.3017])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.2.6b'
macro_revision='1.3017'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

92
m4/lt~obsolete.m4 vendored Normal file
View File

@@ -0,0 +1,92 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# 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 4 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])

4
scripts/Makefile.am Normal file
View File

@@ -0,0 +1,4 @@
EXTRA_DIST = dlt2name.pl
MAINTAINERCLEANFILES = Makefile.in

385
scripts/Makefile.in Normal file
View File

@@ -0,0 +1,385 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = scripts
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/libopts/m4/libopts.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOGEN = @AUTOGEN@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CUT = @CUT@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DMALLOC_LIB = @DMALLOC_LIB@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
GROFF = @GROFF@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LDNETINC = @LDNETINC@
LDNETLIB = @LDNETLIB@
LIBOBJS = @LIBOBJS@
LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
LIBOPTS_DIR = @LIBOPTS_DIR@
LIBOPTS_LDADD = @LIBOPTS_LDADD@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LNAVLIB = @LNAVLIB@
LNAV_CFLAGS = @LNAV_CFLAGS@
LN_S = @LN_S@
LPCAPINC = @LPCAPINC@
LPCAPLIB = @LPCAPLIB@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCAP_BPF_H_FILE = @PCAP_BPF_H_FILE@
PRINTF = @PRINTF@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TCPREPLAY_RELEASE = @TCPREPLAY_RELEASE@
TCPREPLAY_VERSION = @TCPREPLAY_VERSION@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
debug_flag = @debug_flag@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nic1 = @nic1@
nic2 = @nic2@
oldincludedir = @oldincludedir@
pcncfg = @pcncfg@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
tcpdump_path = @tcpdump_path@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = dlt2name.pl
MAINTAINERCLEANFILES = Makefile.in
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu scripts/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

186
scripts/dlt2name.pl Normal file
View File

@@ -0,0 +1,186 @@
#!/usr/bin/perl -w
# Parses the bpf.h header file to generate the dlt_names.h header
# which maps the DLT types to the DLT string name
# run from the tcpreplay source base directory as:
# cat /usr/include/pcap-bpf.h | ./scripts/dlt2name.pl
use strict;
my $out_c = 'src/common/dlt_names.c';
my $out_h = 'src/common/dlt_names.h';
# open outfile
open(OUT_C, ">$out_c") or die("Unable to open $out_c for writing: $!");
open(OUT_H, ">$out_h") or die("Unable to open $out_h for writing: $!");
# read STDIN
# some DLT types aren't in a format we can parse easily or just doesn't
# exist in my /usr/include/net/bpf.h file so we list them here
my %known = (107 => 'BSD/OS Frame Relay',
108 => 'OpenBSD Loopback',
113 => 'Linux Cooked Sockets',
114 => 'Apple LocalTalk',
115 => 'Acorn Econet',
116 => 'OpenBSD IPFilter',
117 => 'OpenBSD PF Log/SuSE 6.3 LANE 802.3',
118 => 'Cisco IOS',
119 => '802.11 Prism Header',
120 => '802.11 Aironet Header',
121 => 'Siemens HiPath HDLC',
122 => 'IP over Fibre Channel'
);
my @names;
# put our known DLT types in names since the format of bpf.h is
# inconsistent
foreach my $dlt (keys %known) {
$names[$dlt]{name} = $known{$dlt};
}
while (my $line = <STDIN>) {
if ($line =~ /^\#define\s+(DLT_[a-zA-Z0-9_]+)\s+(\d+)/) {
my $key = $1;
my $dlt = $2;
my $name = $names[$dlt]{name} ? $names[$dlt]{name} : "";
if ($line =~ /\/\*\s+(.*)\s+\*\//) {
$name = $1;
}
$names[$dlt]{key} = $key;
$names[$dlt]{name} = $name;
}
}
# print the license info
while (my $line = <DATA>) {
print OUT_C $line;
print OUT_H $line;
}
# prep the header
print OUT_C <<HEADER;
#include <stdlib.h>
/* DLT to descriptions */
char *dlt2desc[] = {
HEADER
for (my $i = 0; $i < $#names; $i ++) {
if (! defined $names[$i]) {
print OUT_C "\t\t\"Unknown\",\n";
} else {
print OUT_C "\t\t\"$names[$i]->{name}\",\n";
}
}
print OUT_C <<FOOTER;
\t\tNULL
};
FOOTER
print OUT_H <<HEADER;
/* include all the DLT types form pcap-bpf.h */
extern const char *dlt2desc[];
extern const char *dlt2name[];
#define DLT2DESC_LEN $#names
#define DLT2NAME_LEN $#names
HEADER
for (my $i = 0; $i < 255; $i++) {
next if ! defined $names[$i];
print OUT_H "#ifndef $names[$i]{key}\n#define $names[$i]{key} $i\n#endif\n\n";
}
print OUT_C <<NAMES;
/* DLT to names */
char *dlt2name[] = {
NAMES
for (my $i = 0; $i < 255; $i++) {
if (! defined $names[$i]) {
print OUT_C "\t\t\"Unknown\",\n";
} else {
print OUT_C "\t\t\"$names[$i]{key}\",\n";
}
}
print OUT_C <<FOOTER;
\t\tNULL
};
FOOTER
close OUT_C;
close OUT_H;
exit 0;
__DATA__
/*
* Copyright (c) 2006 Aaron Turner
* All rights reserved.
*
* This file is generated by scripts/dlt2name.pl which converts your pcap-bpf.h
* header file which comes with libpcap into a header file
* which translates DLT values to their string names as well as a list of all
* of the available DLT types.
*
* Hence DO NOT EDIT THIS FILE!
* If your DLT type is not listed here, edit the %known hash in
* scripts/dlt2name.pl
*
* This file contains data which was taken from libpcap's pcap-bpf.h.
* The copyright/license is included below:
*/
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
* The Regents of the University of California. All rights reserved.
*
* This code is derived from the Stanford/CMU enet packet filter,
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
* Berkeley Laboratory.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR 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.
*
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
*
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.34.2.6 2005/08/13 22:29:47 hannes Exp $ (LBL)
*/

472
src/MESA_list.c Normal file
View File

@@ -0,0 +1,472 @@
#include <linux/types.h>
#include <linux/stddef.h>
#include <assert.h>
#include "MESA_list.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*************************** <20>ڲ<EFBFBD>ʵ<EFBFBD>ֽӿ<D6BD> ********************************/
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
static void INIT_LIST_HEAD(struct list_index *head)
{
head->nextele = head;
head->preele = head;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_index *new_list,
struct list_index *prev,
struct list_index *next)
{
next->preele = new_list;
new_list->nextele = next;
new_list->preele = prev;
prev->nextele = new_list;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
* lijia comment: list_add()<29><><EFBFBD>½ڵ<C2BD><DAB5><EFBFBD><EFBFBD><EFBFBD>head<61><64>head->next֮<74><D6AE>.
*/
void list_add(struct list_index *new_list, struct list_index *head)
{
__list_add(new_list, head, head->nextele);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
* lijia comment: list_add_tail()<29><><EFBFBD>½ڵ<C2BD><DAB5><EFBFBD><EFBFBD><EFBFBD>head<61><64>head->prev֮<76><D6AE>.
*/
void list_add_tail(struct list_index *new_list, struct list_index *head)
{
__list_add(new_list, head->preele, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_index * prev, struct list_index * next)
{
next->preele = prev;
prev->nextele = next;
}
static inline void __list_del_entry(struct list_index *entry)
{
__list_del(entry->preele, entry->nextele);
entry->nextele = NULL;
entry->preele = NULL;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static void list_del(struct list_index *entry)
{
__list_del(entry->preele, entry->nextele);
entry->nextele = NULL;
entry->preele = NULL;
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static void list_move(struct list_index *list, struct list_index *head)
{
__list_del_entry(list);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static void list_move_tail(struct list_index *list, struct list_index *head)
{
__list_del_entry(list);
list_add_tail(list, head);
}
#if 0
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static int list_empty(const struct list_index *head)
{
return head->nextele == head;
}
#endif
/**
* list_empty_careful - tests whether a list is empty and not being modified
* @head: the list to test
*
* Description:
* tests whether a list is empty _and_ checks that no other CPU might be
* in the process of modifying either member (next or prev)
*
* NOTE: using list_empty_careful() without synchronization
* can only be safe if the only activity that can happen
* to the list entry is list_del_init(). Eg. it cannot be used
* if another CPU could re-list_add() it.
*/
static int list_empty_careful(const struct list_index *head)
{
MESA_queue_head_t *next = head->nextele;
return (next == head) && (next == head->preele);
}
static inline void list_count_init(void **list_count)
{
long *p_c = (long *)list_count;
*p_c = 0;
}
static inline void list_count_inc(void **list_count)
{
long *p_c = (long *)list_count;
long c = *p_c;
*p_c = c + 1;
}
static inline void list_count_dec(void **list_count)
{
long *p_c = (long *)list_count;
long c = *p_c;
*p_c = c - 1;
}
#if MESA_LIST_CHECK != 0
/*Function:Check the intergrity of the list,to dectect memory mess.
*Input: Queue Head,data check call back function
*Output: return a number below zero,if the queue got a problem,else return 0;
*Author:zhengchao@iie.ac.cn at 20100913
*/
#if 0
static int MESA_q_list_check(const MESA_queue_head_t *qhead_obj,int(*quiddity_check)(const void *))
{
MESA_list_index_t *p=NULL, *head=NULL;
// int linked_ele_number=0;
int ret=0;
// return 0;
if(qhead_obj->listcount==0)
{
if(qhead_obj->head!=NULL||qhead_obj->head!=NULL)
{
ret=-1;
}
goto exit;
}
if(qhead_obj->head==NULL||qhead_obj->tail==NULL)
{
ret=-2;
goto exit;
}
if(qhead_obj->listcount>1){
if(qhead_obj->head->preele!=NULL||qhead_obj->head->nextele==NULL)
{
ret=-3;
goto exit;
}
if(qhead_obj->tail->preele==NULL||qhead_obj->tail->nextele!=NULL)
{
ret=-4;
goto exit;
}
head = p = qhead_obj->head;
p = p->nextele;
while(p != head)
{
if(p == NULL) break;
if(p == head){
ret = -5; /* has a cycle */
goto exit;
}
p = p->nextele;
}
}
/*
pre=qhead_obj->head;
p=pre->nextele;
while(p!=NULL){
linked_ele_number++;
//Is the declared size equal to element linked number;
if(linked_ele_number > qhead_obj->listcount)
{
ret=-5;
goto exit;
}
//Is element's preele pointer equal to its preele
if(pre!=p->preele)
{
ret=-6;
goto exit;
}
if(quiddity_check!=NULL){
if(0>quiddity_check(p->quiddity))
{
ret =-7;
goto exit;
}
}
pre=p;
p=p->nextele;
}
//Is the last element equal to tail
if(pre!=qhead_obj->tail)
{
ret=-8;
goto exit;
}
if(linked_ele_number !=qhead_obj->listcount-1)
{
ret=-9;
goto exit;
}
*/
exit:
if(ret<0)
{
return ret;
}
else
{
return 1;
}
}
#endif
#if 2==MESA_LIST_CHECK
/*Simple check,not raversal*/
static int MESA_q_is_item_in_list(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj){
// MESA_list_index_t* pre=lindex_obj->preele;
// MESA_list_index_t*next=lindex_obj->nextele;
MESA_list_index_t*p=NULL;
int i, num;
if(list_empty_careful(qhead_obj)){
return 0;
}
p = qhead_obj->nextele;
num = MESA_get_list_count(qhead_obj);
i = 0;
while((p != qhead_obj) && (i <= num))
{
if(p == lindex_obj)
{
return 1;
}
p=p->nextele;
i++;
}
return 0;
}
#endif
/*every MESA_list_index_t leaves list,its pre and next will be set NULL
* In Configuration Transmiiter project, not null element will consider in list,
* pre and next is NULL only if there's one element in list only*/
static int MESA_q_is_item_in_list_quick(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
//empty list
if(list_empty_careful(qhead_obj)){
return 0;
}
//have more element
if(lindex_obj->nextele==NULL || lindex_obj->preele==NULL){
return 0;
}
if(lindex_obj->nextele->preele != lindex_obj){
return 0;
}
if(lindex_obj->preele->nextele != lindex_obj){
return 0;
}
return 1;
}
#endif
/*************************** <20>ⲿ<EFBFBD><E2B2BF><EFBFBD>ýӿ<C3BD> ********************************/
/*
<20><>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9>MESA_listģ<74><C4A3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˳<C3B4>ʼ<EFBFBD><CABC>ģ<EFBFBD><C4A3>.
*/
int MESA_list_init(MESA_queue_head_t *head)
{
INIT_LIST_HEAD(head);
list_count_init(&head->quiddity);
return 0;
}
/* <20><>Ϊheadʹ<64><CAB9>ʱ, "quiddity"<22><>Ϊһ<CEAA><D2BB>long<6E>ͱ<EFBFBD><CDB1><EFBFBD>,<2C><><EFBFBD>ڴ洢<DAB4><E6B4A2><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
long MESA_get_list_count(const MESA_queue_head_t *head)
{
return (long)head->quiddity;
}
MESA_list_index_t *MESA_q_read_head(const MESA_queue_head_t *qhead_obj)
{
if(list_empty_careful(qhead_obj)){
return NULL;
}
return qhead_obj->nextele;
}
MESA_list_index_t *MESA_q_get_head(MESA_queue_head_t *qhead_obj)
{
MESA_list_index_t *out;
if(list_empty_careful(qhead_obj)){
return NULL;
}
out = qhead_obj->nextele;
list_del(out);
list_count_dec(&qhead_obj->quiddity);
return out;
}
MESA_list_index_t *MESA_q_get_tail(MESA_queue_head_t *qhead_obj)
{
MESA_list_index_t *out;
if(list_empty_careful(qhead_obj)){
return NULL;
}
out = qhead_obj->preele;
list_del(out);
list_count_dec(&qhead_obj->quiddity);
return out;
}
MESA_list_index_t *MESA_q_join_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
list_add_tail(lindex_obj, qhead_obj);
list_count_inc(&qhead_obj->quiddity);
return lindex_obj;
}
MESA_list_index_t *MESA_q_join_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
list_add(lindex_obj, qhead_obj);
list_count_inc(&qhead_obj->quiddity);
return lindex_obj;
}
MESA_list_index_t *MESA_q_leave_list(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
#if 1==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list_quick(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#elif 2==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#endif
list_del(lindex_obj);
list_count_dec(&qhead_obj->quiddity);
return lindex_obj;
}
MESA_list_index_t *MESA_q_move_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
#if 1==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list_quick(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#elif 2==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#endif
list_move(lindex_obj, qhead_obj);
return lindex_obj;
}
MESA_list_index_t *MESA_q_move_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj)
{
#if 1==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list_quick(qhead_obj,lindex_obj)){
//return NULL;
assert(0); //critical
}
#elif 2==MESA_LIST_CHECK
if(0 == MESA_q_is_item_in_list(qhead_obj, lindex_obj)){
//return NULL;
assert(0); //critical
}
#endif
list_move_tail(lindex_obj, qhead_obj);
return lindex_obj;
}
#ifdef __cplusplus
}
#endif

68
src/MESA_list.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef _MESA_LIST_NEW_H_
#define _MESA_LIST_NEW_H_
#ifdef __cplusplus
extern "C"
{
#endif
#define MESA_LIST_CHECK (1) /* 0:no check; 1:quick check; 2:careful check */
typedef struct list_index {
struct list_index *nextele;
struct list_index *preele;
unsigned char *quiddity;
int pktlen;
}MESA_list_index_t;
typedef struct list_index MESA_queue_head_t;
/* MESA_fixed_queue implement */
typedef struct fixed_qelem{
void *data;
long datalen;
}MESA_fixed_qelem_t;
typedef struct list_index MESA_fixed_q_t;
/*
<20><>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9>MESA_fixed_qģ<71><C4A3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˳<C3B4>ʼ<EFBFBD><CABC>ģ<EFBFBD><C4A3>!!!
*/
int MESA_fixed_q_init(MESA_fixed_q_t *head, long total_elem_num, long max_elem_len);
void MESA_fixed_q_destroy(MESA_fixed_q_t *__head);
long MESA_fixed_q_count(const MESA_fixed_q_t *head);
MESA_fixed_qelem_t *MESA_fixed_q_read_head(MESA_fixed_q_t *head);
MESA_fixed_qelem_t *MESA_fixed_q_get_head(MESA_fixed_q_t *head);
/* In MESA_fixed_queue module, the memory of "data" can not be allocated by malloc, stack memory is alright! */
MESA_fixed_qelem_t *MESA_fixed_q_join_tail(MESA_fixed_q_t *head, void *data, long datalen);
/*
<20><>һ<EFBFBD><D2BB>ʹ<EFBFBD><CAB9>MESA_listģ<74><C4A3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô˳<C3B4>ʼ<EFBFBD><CABC>ģ<EFBFBD><C4A3>!!!
*/
int MESA_list_init(MESA_queue_head_t *head);
long MESA_get_list_count(const MESA_queue_head_t *head);
MESA_list_index_t *MESA_q_read_head(const MESA_queue_head_t *qhead_obj);
MESA_list_index_t *MESA_q_get_head(MESA_queue_head_t *qhead_obj);
MESA_list_index_t *MESA_q_get_tail(MESA_queue_head_t *qhead_obj);
MESA_list_index_t *MESA_q_join_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_join_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_leave_list(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_move_head(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_move_tail(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lindex_obj);
#if 0 /* do do, <20><>δʵ<CEB4><CAB5> */
MESA_list_index_t *MESA_q_join_list_n(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lobj_next, MESA_list_index_t *lindex_obj);
MESA_list_index_t *MESA_q_join_list_p(MESA_queue_head_t *qhead_obj, MESA_list_index_t *lobj_pre, MESA_list_index_t *lindex_obj);
#endif
#ifdef __cplusplus
}
#endif
#endif

122
src/Makefile.am Normal file
View File

@@ -0,0 +1,122 @@
# $Id: Makefile.am 1632 2007-02-03 18:46:16Z aturner $
if COMPILE_FRAGROUTE
LIBFRAGROUTE = ./fragroute/libfragroute.a @LDNETLIB@
FRAGROUTE_DIR = fragroute
else
LIBFRAGROUTE =
FRAGROUTE_DIR =
endif
SUBDIRS = common tcpedit $(FRAGROUTE_DIR)
if SYSTEM_STRLCPY
LIBSTRL =
else
LIBSTRL = ../lib/libstrl.a
endif
manpages: tcpprep.1 tcprewrite.1 tcpreplay.1 tcpbridge.1 tcpreplay-edit.1
autoopts: tcpreplay_opts.c tcprewrite_opts.c tcpbridge_opts.c manpages \
tcpreplay_edit_opts.c
# Get AutoOpts search path
opts_list=-L tcpedit
tcpprep.1: tcpprep_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcpprep tcpprep_opts.def
tcprewrite.1: tcprewrite_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcprewrite tcprewrite_opts.def
tcpreplay-edit.1: tcpreplay_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) -DTCPREPLAY_EDIT --base-name tcpreplay-edit tcpreplay_opts.def
tcpreplay.1: tcpreplay_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcpreplay tcpreplay_opts.def
tcpbridge.1: tcpbridge_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ -T agman1.tpl $(opts_list) --base-name tcpbridge tcpbridge_opts.def
man_MANS = tcpreplay.1 tcpprep.1 tcprewrite.1 tcpreplay-edit.1
EXTRA_DIST = tcpreplay.1 tcpprep.1 tcprewrite.1 tcpbridge.1 tcpreplay-edit.1
bin_PROGRAMS = tcpreplay tcpprep tcprewrite tcpreplay-edit
if COMPILE_TCPBRIDGE
bin_PROGRAMS += tcpbridge
man_MANS += tcpbridge.1
endif
tcpreplay_edit_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPREPLAY -DTCPREPLAY_EDIT -DHAVE_CACHEFILE_SUPPORT
tcpreplay_edit_LDADD = ./tcpedit/libtcpedit.a ./common/libcommon.a ./suppport_lib/libMESA_prof_load.a $(LIBSTRL) @LPCAPLIB@ @LDNETLIB@ $(LIBOPTS_LDADD)
tcpreplay_edit_SOURCES = tcpreplay_edit_opts.c send_packets.c signal_handler.c tcpreplay.c sleep.c
tcpreplay_edit_OBJECTS: tcpreplay_opts.h
tcpreplay_edit_opts.h: tcpreplay_edit_opts.c
tcpreplay_edit_opts.c: tcpreplay_opts.def
@AUTOGEN@ $(opts_list) -DTCPREPLAY_EDIT -b tcpreplay_edit_opts \
tcpreplay_opts.def
tcpreplay_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPREPLAY
tcpreplay_SOURCES = tcpreplay_opts.c send_packets.c signal_handler.c tcpreplay.c sleep.c
tcpreplay_LDADD = ./common/libcommon.a ./suppport_lib/libMESA_prof_load.a $(LIBSTRL) @LPCAPLIB@ @LDNETLIB@ $(LIBOPTS_LDADD)
tcpreplay_OBJECTS: tcpreplay_opts.h
tcpreplay_opts.h: tcpreplay_opts.c
tcpreplay_opts.c: tcpreplay_opts.def
@AUTOGEN@ $(opts_list) tcpreplay_opts.def
if ENABLE_OSX_FRAMEWORKS
tcpreplay_LDFLAGS = -framework CoreServices -framework Carbon
tcpreplay_edit_LDFLAGS = -framework CoreServices -framework Carbon
endif
tcprewrite_CFLAGS = $(LIBOPTS_CFLAGS) -I.. @LDNETINC@ $(LNAV_CFLAGS) -DTCPREWRITE -DHAVE_CACHEFILE_SUPPORT
tcprewrite_LDADD = ./tcpedit/libtcpedit.a ./common/libcommon.a ./suppport_lib/libMESA_prof_load.a \
$(LIBSTRL) @LPCAPLIB@ $(LIBOPTS_LDADD) @DMALLOC_LIB@ \
$(LIBFRAGROUTE)
tcprewrite_SOURCES = tcprewrite_opts.c tcprewrite.c
tcprewrite_OBJECTS: tcprewrite_opts.h
tcprewrite_opts.h: tcprewrite_opts.c
tcprewrite_opts.c: tcprewrite_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ $(opts_list) tcprewrite_opts.def
tcpprep_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPPREP
tcpprep_LDADD = ./common/libcommon.a suppport_lib/libMESA_prof_load.a \
$(LIBSTRL) @LPCAPLIB@ $(LIBOPTS_LDADD) @DMALLOC_LIB@
tcpprep_SOURCES = tcpprep_opts.c tcpprep.c tree.c
tcpprep_OBJECTS: tcpprep_opts.h
tcpprep_opts.h: tcpprep_opts.c
tcpprep_opts.c: tcpprep_opts.def
@AUTOGEN@ tcpprep_opts.def
tcpbridge_CFLAGS = $(LIBOPTS_CFLAGS) -I.. $(LNAV_CFLAGS) @LDNETINC@ -DTCPBRIDGE
tcpbridge_LDADD = ./tcpedit/libtcpedit.a ./common/libcommon.a suppport_lib/libMESA_prof_load.a \
$(LIBSTRL) @LPCAPLIB@ @LDNETLIB@ $(LIBOPTS_LDADD) @DMALLOC_LIB@
if ENABLE_OSX_FRAMEWORKS
tcpbridge_LDFLAGS = -framework CoreServices -framework Carbon
endif
tcpbridge_SOURCES = tcpbridge_opts.c tcpbridge.c bridge.c send_packets.c sleep.c
tcpbridge_OBJECTS: tcpbridge_opts.h
tcpbridge_opts.h: tcpbridge_opts.c
tcpbridge_opts.c: tcpbridge_opts.def tcpedit/tcpedit_opts.def
@AUTOGEN@ $(opts_list) tcpbridge_opts.def
noinst_HEADERS = tcpreplay.h tcpprep.h bridge.h defines.h tree.h \
send_packets.h signal_handler.h common.h tcpreplay_opts.h \
tcpreplay_edit_opts.h tcprewrite.h tcprewrite_opts.h tcpprep_opts.h \
tcpprep_opts.def tcprewrite_opts.def tcpreplay_opts.def \
tcpbridge_opts.def tcpbridge.h tcpbridge_opts.h tcpr.h sleep.h
MOSTLYCLEANFILES = *~ *.o
MAINTAINERCLEANFILES = Makefile.in tcpreplay_opts.h tcpreplay_opts.c \
tcprewrite_opts.c tcprewrite_opts.h tcpprep_opts.c \
tcpprep_opts.h tcpprep.1 tcpreplay.1 tcprewrite.1 \
tcpbridge.1 tcpbridge_opts.h tcpbridge_opts.c \
tcpreplay_edit_opts.c tcpreplay_edit_opts.h \
tcpreplay-edit.1

Some files were not shown because too many files have changed in this diff Show More