first commit

pull/37/merge
tstack 15 years ago
commit b4ec432515

@ -0,0 +1,229 @@
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
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 only 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. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. 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=c89 CFLAGS=-O2 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 must use a version of `make' that
supports the `VPATH' variable, such as 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 `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have 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' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' 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 `--target=TYPE' option 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
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`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.

@ -0,0 +1,6 @@
ACLOCAL_AMFLAGS = -I .
SUBDIRS = src test
noinst_SCRIPTS = TESTS_ENVIRONMENT

@ -0,0 +1,615 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 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@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@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@
subdir = .
DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/TESTS_ENVIRONMENT.in \
$(top_srcdir)/configure INSTALL config.guess config.sub \
depcomp install-sh missing mkinstalldirs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_sqlite3.m4 \
$(top_srcdir)/lnav.m4 $(top_srcdir)/configure.in
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)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES = TESTS_ENVIRONMENT
SCRIPTS = $(noinst_SCRIPTS)
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
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
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); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CFLAGS_PG = @CFLAGS_PG@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIB = @CURSES_LIB@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCRE_CFLAGS = @PCRE_CFLAGS@
PCRE_LIBS = @PCRE_LIBS@
RANLIB = @RANLIB@
READLINE_CFLAGS = @READLINE_CFLAGS@
READLINE_LIBS = @READLINE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCI_CXXFLAGS = @SOCI_CXXFLAGS@
SOCI_LIBS = @SOCI_LIBS@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LDFLAGS = @SQLITE3_LDFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
SQLITE3_VERSION = @SQLITE3_VERSION@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
abssrcdir = @abssrcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
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@
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@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ACLOCAL_AMFLAGS = -I .
SUBDIRS = src test
noinst_SCRIPTS = TESTS_ENVIRONMENT
all: all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
cd $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
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: $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
TESTS_ENVIRONMENT: $(top_builddir)/config.status $(srcdir)/TESTS_ENVIRONMENT.in
cd $(top_builddir) && $(SHELL) ./config.status $@
# 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):
@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; \
(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):
@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; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (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; nonemtpy = 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)
tags=; \
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 || \
tags="$$tags $$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; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
am__remove_distdir=: \
am__skip_length_check=: \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -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-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) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(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)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& 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
$(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:
@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 $(SCRIPTS)
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:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-exec-am:
install-html: install-html-recursive
install-info: install-info-recursive
install-man:
install-pdf: install-pdf-recursive
install-ps: install-ps-recursive
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
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \
install-strip
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \
distclean-generic 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 pdf pdf-am ps ps-am tags \
tags-recursive 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:

@ -0,0 +1,103 @@
#! /bin/sh
top_srcdir="@abssrcdir@"
export top_srcdir
# The top build directory, derived from the path to this script.
top_builddir=`dirname $0`
# The full path of the test case
test_file=$1
# The base name of the test case
test_file_base=`basename $1`
# The current test number for shell based tests.
test_num=0
## BEGIN Functions
LAST_TEST=""
#
# Run a test case and capture its standard out and standard err.
#
# Usage: run_test <utility> [<argument> ...]
#
# Example:
#
# To run rktimes and capture all of its stdio output:
#
# run_test rktimes -V
#
run_test() {
LAST_TEST="test: $@"
"$@" > ${test_file_base}_${test_num}.tmp 2>&1
}
#
# Check the output generated by a run_test() call.
#
# Usage: check_output <fail message> {Expected output on stdin}
#
# Example:
#
# To check the output of 'rktimes -V' and print out 'Unable to get version?'
# if the output doesn't match:
#
# run_test rktimes -V
# check_output "Unable to get version?" <<EOF
# 0.5
# EOF
#
check_output() {
cmp ${test_file_base}_${test_num}.tmp -
if test $? -ne 0; then
echo $LAST_TEST
echo $1
exit 1
fi
test_num=`expr ${test_num} \+ 1`
}
#
# Grep for a string in the output generated by a run_test() call.
#
# Usage: grep_output_for <string> <fail maessage>
#
# Example:
#
# To check the output of 'cbhey -l' for 'IDL:Foobar:1.0' and print out
# 'Unable to list supported interfaces?' if it is not found:
#
# run_test cbhey -l
# grep_output_for "IDL:Foobar:1.0" "Unable to list supported interface?"
#
grep_output_for() {
if grep -q $1 ${test_file_base}_${test_num}.tmp > /dev/null 2>&1; then
:
else
echo "${test_file_base}_${test_num}.tmp: $2"
exit 1
fi
test_num=`expr ${test_num} \+ 1`
}
on_error_fail_with() {
if test $? -ne 0; then
echo $1 > /dev/stderr
exit 1
fi
}
## END Functions
# Finally, run the test...
if test -x $1 && test `basename $1 .sh` == `basename $1`; then
exec $*
else
# Shell script
shift
. ${test_file}
fi

882
aclocal.m4 vendored

@ -0,0 +1,882 @@
# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# 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.
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(AC_AUTOCONF_VERSION, [2.61],,
[m4_warning([this file was generated for autoconf 2.61.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.10'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.10.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
# _AM_AUTOCONF_VERSION(VERSION)
# -----------------------------
# aclocal traces this macro to find the Autoconf version.
# This is a private macro too. Using m4_define simplifies
# the logic in aclocal, which can simply ignore this definition.
m4_define([_AM_AUTOCONF_VERSION], [])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.10.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[dnl Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])dnl
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 8
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 9
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], UPC, [depcc="$UPC" am_compiler_list=],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
# Solaris 8's {/usr,}/bin/sh.
touch sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
#serial 3
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 8
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 13
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.60])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
# test to see if srcdir already configured
if test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES(OBJC)],
[define([AC_PROG_OBJC],
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
])
])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_arg=$1
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 3
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo done
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 5
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
AC_DEFUN([AM_PROG_MKDIR_P],
[AC_PREREQ([2.60])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
dnl while keeping a definition of mkdir_p for backward compatibility.
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
dnl Makefile.ins that do not define MKDIR_P, so we do our own
dnl adjustment using top_builddir (which is defined more often than
dnl MKDIR_P).
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
case $mkdir_p in
[[\\/$]]* | ?:[[\\/]]*) ;;
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
esac
])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 3
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 4
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
# FORMAT should be one of `v7', `ustar', or `pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
# $tardir.
# tardir=directory && $(am__tar) > result.tar
#
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility.
AM_MISSING_PROG([AMTAR], [tar])
m4_if([$1], [v7],
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
# Do not fold the above two line into one, because Tru64 sh and
# Solaris sh will not grok spaces in the rhs of `-'.
for _am_tool in $_am_tools
do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar;
do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
m4_include([ax_sqlite3.m4])
m4_include([lnav.m4])

@ -0,0 +1,6 @@
#! /bin/sh
aclocal -I .
autoheader -I .
automake --add-missing --copy --foreign
autoconf

@ -0,0 +1,154 @@
dnl $Id: ax_sqlite3.m4,v 1.2 2006/08/30 14:28:55 mloskot Exp $
dnl
dnl @synopsis AX_LIB_SQLITE3([MINIMUM-VERSION])
dnl
dnl Test for the SQLite 3 library of a particular version (or newer)
dnl
dnl This macro takes only one optional argument, required version
dnl of SQLite 3 library. If required version is not passed,
dnl 3.0.0 is used in the test of existance of SQLite 3.
dnl
dnl If no intallation prefix to the installed SQLite library is given
dnl the macro searches under /usr, /usr/local, and /opt.
dnl
dnl This macro calls:
dnl
dnl AC_SUBST(SQLITE3_CFLAGS)
dnl AC_SUBST(SQLITE3_LDFLAGS)
dnl AC_SUBST(SQLITE3_LIBS)
dnl AC_SUBST(SQLITE3_VERSION)
dnl
dnl And sets:
dnl
dnl HAVE_SQLITE3
dnl
dnl @category InstalledPackages
dnl @category Cxx
dnl @author Mateusz Loskot <mateusz@loskot.net>
dnl @version $Date: 2006/08/30 14:28:55 $
dnl @license AllPermissive
dnl
dnl $Id: ax_sqlite3.m4,v 1.2 2006/08/30 14:28:55 mloskot Exp $
dnl
AC_DEFUN([AX_LIB_SQLITE3],
[
AC_ARG_WITH([sqlite3],
AC_HELP_STRING(
[--with-sqlite3=@<:@ARG@:>@],
[use SQLite 3 library @<:@default=yes@:>@, optionally specify the prefix for sqlite3 library]
),
[
if test "$withval" = "no"; then
WANT_SQLITE3="no"
elif test "$withval" = "yes"; then
WANT_SQLITE3="yes"
ac_sqlite3_path=""
else
WANT_SQLITE3="yes"
ac_sqlite3_path="$withval"
fi
],
[WANT_SQLITE3="yes"]
)
SQLITE3_CFLAGS=""
SQLITE3_LDFLAGS=""
SQLITE3_LIBS=""
SQLITE3_VERSION=""
if test "x$WANT_SQLITE3" = "xyes"; then
ac_sqlite3_header="sqlite3.h"
sqlite3_version_req=ifelse([$1], [], [3.0.0], [$1])
sqlite3_version_req_shorten=`expr $sqlite3_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
sqlite3_version_req_major=`expr $sqlite3_version_req : '\([[0-9]]*\)'`
sqlite3_version_req_minor=`expr $sqlite3_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
sqlite3_version_req_micro=`expr $sqlite3_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
if test "x$sqlite3_version_req_micro" = "x" ; then
sqlite3_version_req_micro="0"
fi
sqlite3_version_req_number=`expr $sqlite3_version_req_major \* 1000000 \
\+ $sqlite3_version_req_minor \* 1000 \
\+ $sqlite3_version_req_micro`
AC_MSG_CHECKING([for SQLite3 library >= $sqlite3_version_req])
if test "$ac_sqlite3_path" != ""; then
ac_sqlite3_ldflags="-L$ac_sqlite3_path/lib"
ac_sqlite3_cppflags="-I$ac_sqlite3_path/include"
else
for ac_sqlite3_path_tmp in /usr /usr/local /opt ; do
if test -f "$ac_sqlite3_path_tmp/include/$ac_sqlite3_header" \
&& test -r "$ac_sqlite3_path_tmp/include/$ac_sqlite3_header"; then
ac_sqlite3_path=$ac_sqlite3_path_tmp
ac_sqlite3_ldflags="-I$ac_sqlite3_path_tmp/include"
ac_sqlite3_cppflags="-L$ac_sqlite3_path_tmp/lib"
break;
fi
done
fi
ac_sqlite3_ldflags="$ac_sqlite3_ldflags"
ac_sqlite3_libs="-lsqlite3"
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $ac_sqlite3_cppflags"
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE(
[
AC_LANG_PROGRAM([[@%:@include <sqlite3.h>]],
[[
#if (SQLITE_VERSION_NUMBER >= $sqlite3_version_req_number)
// Everything is okay
#else
# error SQLite version is too old
#endif
]]
)
],
[
AC_MSG_RESULT([yes])
success="yes"
],
[
AC_MSG_RESULT([not found])
succees="no"
]
)
AC_LANG_POP([C++])
CPPFLAGS="$saved_CPPFLAGS"
if test "$success" = "yes"; then
SQLITE3_CFLAGS="$ac_sqlite3_cppflags"
SQLITE3_LDFLAGS="$ac_sqlite3_ldflags"
SQLITE3_LIBS="$ac_sqlite3_libs"
ac_sqlite3_header_path="$ac_sqlite3_path/include/$ac_sqlite3_header"
dnl Retrieve SQLite release version
if test "x$ac_sqlite3_header_path" != "x"; then
ac_sqlite3_version=`cat $ac_sqlite3_header_path \
| grep '#define.*SQLITE_VERSION.*\"' | sed -e 's/.* "//' \
| sed -e 's/"//'`
if test $ac_sqlite3_version != ""; then
SQLITE3_VERSION=$ac_sqlite3_version
else
AC_MSG_WARN([Can not find SQLITE_VERSION macro in sqlite3.h header to retrieve SQLite version!])
fi
fi
AC_DEFINE([HAVE_SQLITE3], [], [sqlite3])
fi
fi
AC_SUBST(SQLITE3_CFLAGS)
AC_SUBST(SQLITE3_LDFLAGS)
AC_SUBST(SQLITE3_LIBS)
AC_SUBST(SQLITE3_VERSION)
])

1354
config.guess vendored

File diff suppressed because it is too large Load Diff

1460
config.sub vendored

File diff suppressed because it is too large Load Diff

8719
configure vendored

File diff suppressed because it is too large Load Diff

@ -0,0 +1,84 @@
AC_INIT(lnav, 0.1.0, timothyshanestack@gmail.com)
AC_CONFIG_SRCDIR([src/lnav.cc])
AM_INIT_AUTOMAKE(lnav, 0.1.0)
AC_PREFIX_DEFAULT(/usr/)
AC_CANONICAL_HOST
dnl abssrcdir is the absolute path to the source base (regardless of where
dnl you are building it)
case x$srcdir in
x/*)
abssrcdir=$srcdir
;;
*)
abssrcdir=`pwd`/$srcdir
;;
esac
AC_SUBST(abssrcdir)
AC_PROG_CXX
#CFLAGS=`echo $CFLAGS | sed 's/-O2//g'`
#CXXFLAGS=`echo $CXXFLAGS | sed 's/-O2//g'`
AC_ARG_ENABLE([profiling],
AS_HELP_STRING([--enable-profiling],
[Compile with gprof(1) profiling support]))
AC_MSG_CHECKING(gprof(4) profiling support)
if test x"${enable_profiling}" = x"yes" ; then
CFLAGS="$CFLAGS -pg -gstabs"
CXXFLAGS="$CXXFLAGS -pg -gstabs"
LDFLAGS="$LDFLAGS -pg"
else
enable_profiling=no
fi
AC_MSG_RESULT($enable_profiling)
AC_SUBST(CFLAGS_PG)
AC_PROG_INSTALL
AC_PROG_RANLIB
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_CHECK_SIZEOF(off_t)
AC_CHECK_SIZEOF(size_t)
AC_CHECK_PROG(OBJCOPY, objcopy, objcopy)
AM_CONDITIONAL(HAVE_OBJCOPY, test x"$OBJCOPY" != x"")
AC_SEARCH_LIBS(openpty, util)
AC_CHECK_HEADERS(pty.h util.h)
MP_WITH_CURSES()
AX_PATH_LIB_PCRE([], [AC_MSG_ERROR([pcre required to build])])
AX_PATH_LIB_READLINE([], [AC_MSG_ERROR([readline required to build])])
AX_LIB_SQLITE3("3.0.0")
AX_PATH_LIB_SOCI([], [AC_MSG_ERROR([soci required to build])])
AM_CONDITIONAL(HAVE_SOCI, test x"$SOCI_CXXFLAGS" != x"")
AM_CONDITIONAL(HAVE_LIBSQLITE3, [
test -n "$SQLITE3_CFLAGS" -a -n "$SQLITE3_LDFLAGS"])
case "$host_os" in
darwin*)
AC_DEFINE([_APPLE_C_SOURCE], [], [Needed for the 'timezone' variable])
;;
*)
AC_DEFINE([_XOPEN_SOURCE], [500], [Need pread])
AC_DEFINE([_BSD_SOURCE], [], [Need pread])
;;
esac
AM_CONFIG_HEADER([src/config.h])
AC_CONFIG_FILES([Makefile])
AC_CONFIG_FILES([TESTS_ENVIRONMENT])
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([test/Makefile])
AC_OUTPUT

@ -0,0 +1,423 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000 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>.
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. 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.
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
outname="$stripped.o"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
# 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"
;;
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
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
else
tmpdepfile="$tmpdepfile2"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a space and a tab 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 proprocessed 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'. We will use -o /dev/null later,
# however we can't do the remplacement now because
# `-o $object' might simply not be used
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
"$@" -o /dev/null $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 $?
# 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 ;;
-*)
;;
*)
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 proprocessed 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 proprocessed 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

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# 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=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -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 [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -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 [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
:
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
:
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# 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.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

@ -0,0 +1,543 @@
#
# General options
#
# The type of line endings
newlines = lf # auto/lf/crlf/cr
# The original size of tabs in the input
input_tab_size = 8 # number
# The size of tabs in the output (only used if align_with_tabs=true)
output_tab_size = 8 # number
# The ascii value of the string escape char, usually 92 (\). (Pawn)
string_escape_char = 92 # number
#
# Indenting
#
# The number of columns to indent per level (usually 2, 3, 4, or 8)
indent_columns = 4 # number
# How to use tabs when indenting code
# 0=spaces only
# 1=indent with tabs, align with spaces
# 2=indent and align with tabs
indent_with_tabs = 2 # number
# Whether to indent strings broken by '\' so that they line up
indent_align_string = false # false/true
# Spaces to indent '{' from level
indent_brace = 0 # number
# Whether braces are indented to the body level
indent_braces = false # false/true
# Disabled indenting function braces if indent_braces is true
indent_braces_no_func = false # false/true
# Indent based on the size of the brace parent, ie 'if' => 3 spaces, 'for' => 4 spaces, etc.
indent_brace_parent = false # false/true
# Whether the 'namespace' body is indented
indent_namespace = false # false/true
# Whether the 'class' body is indented
indent_class = true # false/true
# Whether to indent the stuff after a leading class colon
indent_class_colon = true # false/true
# Whether to indent continued function call parameters one indent level (true) or aligns instead of indent (false)
indent_func_call_param = false # false/true
# The number of spaces to indent a continued '->' or '.'
# Usually set to indent_columns.
indent_member = 0 # number
# Spaces to indent single line ('//') comments on lines before code
indent_sing_line_comments = 0 # number
# Spaces to indent 'case' from 'switch'
indent_switch_case = 0 # number
# Spaces to indent 'case' body from 'case'
indent_case_body = 0 # number
# Spaces to indent '{' from 'case'
indent_case_brace = 0 # number
# Whether to indent comments found in first column
indent_col1_comment = false # false/true
# How to indent goto labels (>0=absolute column where 1 is the leftmost column, <=0=subtract from brace indent)
indent_label = 1 # number
# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended)
indent_paren_nl = false # false/true
# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended)
indent_square_nl = false # false/true
#
# Spacing options
#
# Add or remove space around arithmetic operator '+', '-', '/', '*', etc
sp_arith = force # ignore/add/remove/force
# Add or remove space around assignment operator '=', '+=', etc
sp_assign = force # ignore/add/remove/force
# Add or remove space around boolean operators '&&' and '||'
sp_bool = force # ignore/add/remove/force
# Add or remove space around compare operator '<', '>', '==', etc
sp_compare = force # ignore/add/remove/force
# Add or remove space inside '(' and ')'
sp_inside_paren = remove # ignore/add/remove/force
# Add or remove space between nested parens
sp_paren_paren = remove # ignore/add/remove/force
# Add or remove space between ')' and '{'
sp_paren_brace = ignore # ignore/add/remove/force
# Add or remove space before pointer star '*'
sp_before_ptr_star = force # ignore/add/remove/force
# Add or remove space between pointer stars '*'
sp_between_ptr_star = remove # ignore/add/remove/force
# Add or remove space after pointer star '*'
sp_after_ptr_star = remove # ignore/add/remove/force
# Add or remove space before reference sign '&'
sp_before_byref = force # ignore/add/remove/force
# Add or remove space after reference sign '&'
sp_after_byref = ignore # ignore/add/remove/force
# Add or remove space before '<>'
sp_before_angle = remove # ignore/add/remove/force
# Add or remove space after '<>'
sp_after_angle = force # ignore/add/remove/force
# Add or remove space before '(' of 'if', 'for', 'switch', and 'while'
sp_before_sparen = force # ignore/add/remove/force
# Add or remove space inside if-condition '(' and ')'
sp_inside_sparen = remove # ignore/add/remove/force
# Add or remove space after ')' of 'if', 'for', 'switch', and 'while'
sp_after_sparen = force # ignore/add/remove/force
# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while'
sp_sparen_brace = add # ignore/add/remove/force
# Add or remove space before empty statement ';' on 'if', 'for' and 'while'
sp_special_semi = ignore # ignore/add/remove/force
# Add or remove space before ';'
sp_before_semi = remove # ignore/add/remove/force
# Add or remove space before '[' (except '[]')
sp_before_square = ignore # ignore/add/remove/force
# Add or remove space before '[]'
sp_before_squares = ignore # ignore/add/remove/force
# Add or remove space inside '[' and ']'
sp_inside_square = remove # ignore/add/remove/force
# Add or remove space after ','
sp_after_comma = force # ignore/add/remove/force
# Add or remove space between 'operator' and operator sign
sp_after_operator = ignore # ignore/add/remove/force
# Add or remove space after cast
sp_after_cast = remove # ignore/add/remove/force
# Add or remove space between 'sizeof' and '('
sp_sizeof_paren = remove # ignore/add/remove/force
# Add or remove space after the tag keyword (Pawn)
sp_after_tag = ignore # ignore/add/remove/force
# Add or remove space inside enum '{' and '}'
sp_inside_braces_enum = force # ignore/add/remove/force
# Add or remove space inside struct/union '{' and '}'
sp_inside_braces_struct = force # ignore/add/remove/force
# Add or remove space inside '{' and '}'
sp_inside_braces = force # ignore/add/remove/force
# Add or remove space inside '<' and '>'
sp_inside_angle = remove # ignore/add/remove/force
# Add or remove space between return type and function name (a minimum of 1 is forced except for pointer return types)
sp_type_func = ignore # ignore/add/remove/force
# Add or remove space between function name and '(' on function declaration
sp_func_proto_paren = remove # ignore/add/remove/force
# Add or remove space between function name and '(' on function definition
sp_func_def_paren = remove # ignore/add/remove/force
# Add or remove space inside empty function '()'
sp_inside_fparens = ignore # ignore/add/remove/force
# Add or remove space inside function '(' and ')'
sp_inside_fparen = remove # ignore/add/remove/force
# Add or remove space between ']' and '(' when part of a function call.
sp_square_fparen = ignore # ignore/add/remove/force
# Add or remove space between ')' and '{' of function
sp_fparen_brace = add # ignore/add/remove/force
# Add or remove space between function name and '(' on function calls
sp_func_call_paren = remove # ignore/add/remove/force
# Add or remove space between a constructor/destructor and the open paren
sp_func_class_paren = remove # ignore/add/remove/force
# Add or remove space between 'return' and '('
sp_return_paren = add # ignore/add/remove/force
# Add or remove space between macro and value
sp_macro = ignore # ignore/add/remove/force
# Add or remove space between macro function ')' and value
sp_macro_func = ignore # ignore/add/remove/force
# Add or remove space between 'else' and '{' if on the same line
sp_else_brace = ignore # ignore/add/remove/force
# Add or remove space between '}' and 'else' if on the same line
sp_brace_else = ignore # ignore/add/remove/force
#
# Code alignment (not left column spaces/tabs)
#
# Whether to keep non-indenting tabs
align_keep_tabs = false # false/true
# Whether to use tabs for alinging
align_with_tabs = false # false/true
# Whether to bump out to the next tab when aligning
align_on_tabstop = false # false/true
# Whether to left-align numbers
align_number_left = true # false/true
# The span for aligning variable definitions (0=don't align)
align_var_def_span = 1 # number
# Whether the pointer star is part of the variable name or not
align_var_def_star = true # false/true
# The threshold for aligning variable definitions (0=no limit)
align_var_def_thresh = 12 # number
# Whether to align the colon in struct bit fields
align_var_def_colon = true # false/true
# Whether to align inline struct/enum/union variable definitions
align_var_def_inline = true # false/true
# The span for aligning on '=' in assignments (0=don't align)
align_assign_span = 1 # number
# The threshold for aligning on '=' in assignments (0=no limit)
align_assign_thresh = 12 # number
# The span for aligning on '=' in enums (0=don't align)
align_enum_equ_span = 4 # number
# The threshold for aligning on '=' in enums (0=no limit)
align_enum_equ_thresh = 0 # number
# The span for aligning struct/union (0=don't align)
align_var_struct_span = 99 # number
# The span for aligning struct initializer values (0=don't align)
align_struct_init_span = 3 # number
# The minimum space between the type and the synonym of a typedef
align_typedef_gap = 1 # number
# The span for aligning single-line typedefs (0=don't align)
align_typedef_span = 5 # number
# Controls the positioning of the '*' in typedefs. Just try it.
# 0: Align on typdef type, ignore '*'
# 1: The '*' is part of type name: typedef int *pint;
# 2: The '*' is part of the type: typedef int * pint;
align_typedef_star_style = 1 # number
# The span for aligning comments that end lines (0=don't align)
align_right_cmt_span = 3 # number
# The span for aligning function prototypes (0=don't align)
align_func_proto_span = 0 # number
# Whether to align macros wrapped with a backslash and a newline
align_nl_cont = true # false/true
# The minimum space between label and value of a preprocessor define
align_pp_define_gap = 4 # number
# The span for aligning on '#define' bodies (0=don't align)
align_pp_define_span = 3 # number
#
# Newline adding and removing options
#
# Try to limit code width to N number of columns
code_width = 0 # number
# Whether to collapse empty blocks between '{' and '}'
nl_collapse_empty_body = true # false/true
# Don't touch one-line function bodies inside a class xx { } body
nl_class_leave_one_liners = true # false/true
# Add or remove newlines at the start of the file
nl_start_of_file = remove # ignore/add/remove/force
# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force'
nl_start_of_file_min = 0 # number
# Add or remove newline at the end of the file
nl_end_of_file = force # ignore/add/remove/force
# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force')
nl_end_of_file_min = 1 # number
# Add or remove newline between '=' and '{'
nl_assign_brace = remove # ignore/add/remove/force
# The number of newlines after a block of variable definitions
nl_func_var_def_blk = 1 # number
# Add or remove newline between function call and '('
nl_fcall_brace = add # ignore/add/remove/force
# Add or remove newline between 'enum' and '{'
nl_enum_brace = remove # ignore/add/remove/force
# Add or remove newline between 'struct and '{'
nl_struct_brace = remove # ignore/add/remove/force
# Add or remove newline between 'union' and '{'
nl_union_brace = remove # ignore/add/remove/force
# Add or remove newline between 'if' and '{'
nl_if_brace = remove # ignore/add/remove/force
# Add or remove newline between '}' and 'else'
nl_brace_else = add # ignore/add/remove/force
# Add or remove newline between 'else if' and '{'
# If set to ignore, nl_if_brace is used instead
nl_elseif_brace = remove # ignore/add/remove/force
# Add or remove newline between 'else' and '{'
nl_else_brace = remove # ignore/add/remove/force
# Add or remove newline between 'for' and '{'
nl_for_brace = remove # ignore/add/remove/force
# Add or remove newline between 'while' and '{'
nl_while_brace = remove # ignore/add/remove/force
# Add or remove newline between 'do' and '{'
nl_do_brace = remove # ignore/add/remove/force
# Add or remove newline between '}' and 'while' of 'do' statement
nl_brace_while = remove # ignore/add/remove/force
# Add or remove newline between 'switch' and '{'
nl_switch_brace = remove # ignore/add/remove/force
# Whether to put a newline before 'case' statement
nl_before_case = true # false/true
# Whether to put a newline after 'case' statement
nl_after_case = false # false/true
# Newline between namespace and {
nl_namespace_brace = ignore # ignore/add/remove/force
# Add or remove newline between 'template<>' and 'class'
nl_template_class = add # ignore/add/remove/force
# Add or remove newline between 'class' and '{'
nl_class_brace = remove # ignore/add/remove/force
# Add or remove newline after each ',' in the constructor member initialization
nl_class_init_args = add # ignore/add/remove/force
# Add or remove newline between return type and function name in definition
nl_func_type_name = ignore # ignore/add/remove/force
# Add or remove newline after '(' in a function declaration
nl_func_decl_start = ignore # ignore/add/remove/force
# Add or remove newline after each ',' in a function declaration
nl_func_decl_args = ignore # ignore/add/remove/force
# Add or remove newline before the ')' in a function declaration
nl_func_decl_end = ignore # ignore/add/remove/force
# Add or remove newline between function signature and '{'
nl_fdef_brace = add # ignore/add/remove/force
# Whether to put a newline after 'return' statement
nl_after_return = true # false/true
# Whether to put a newline after semicolons, except in 'for' statements
nl_after_semicolon = false # false/true
# Whether to put a newline after brace open
nl_after_brace_open = false # false/true
# Whether to alter newlines in '#define' macros
nl_define_macro = false # false/true
# Whether to not put blanks after '#ifxx', '#elxx', or before '#endif'
nl_squeeze_ifdef = true # false/true
# Add or remove newline before 'if'
nl_before_if = ignore # ignore/add/remove/force
# Add or remove newline after 'if'
nl_after_if = ignore # ignore/add/remove/force
# Add or remove newline before 'for'
nl_before_for = ignore # ignore/add/remove/force
# Add or remove newline after 'for'
nl_after_for = ignore # ignore/add/remove/force
# Add or remove newline before 'while'
nl_before_while = ignore # ignore/add/remove/force
# Add or remove newline after 'while'
nl_after_while = ignore # ignore/add/remove/force
# Add or remove newline before 'switch'
nl_before_switch = ignore # ignore/add/remove/force
# Add or remove newline after 'switch'
nl_after_switch = ignore # ignore/add/remove/force
# Add or remove newline before 'do'
nl_before_do = ignore # ignore/add/remove/force
# Add or remove newline after 'do'
nl_after_do = ignore # ignore/add/remove/force
#
# Positioning options
#
# The position of boolean operators in wrapped expressions
pos_bool = trail # ignore/lead/trail
# The position of colons between constructor and member initialization
pos_class_colon = lead # ignore/lead/trail
#
# Blank line options
#
# The maximum consecutive newlines
nl_max = 4 # number
# The number of newlines after a function prototype, if followed by another function prototype
nl_after_func_proto = 0 # number
# The number of newlines after a function prototype, if not followed by another function prototype
nl_after_func_proto_group = 2 # number
# The number of newlines after '}' of the function body
nl_after_func_body = 2 # number
# The minimum number of newlines before a multi-line comment (doesn't apply if after a brace open)
nl_before_block_comment = 2 # number
# Whether to remove blank lines after '{'
eat_blanks_after_open_brace = true # false/true
# Whether to remove blank lines before '}'
eat_blanks_before_close_brace = true # false/true
#
# Code modifying options (non-whitespace)
#
# Add or remove braces on single-line 'do' statement
mod_full_brace_do = add # ignore/add/remove/force
# Add or remove braces on single-line 'for' statement
mod_full_brace_for = add # ignore/add/remove/force
# Add or remove braces on single-line function defintions. (Pawn)
mod_full_brace_function = ignore # ignore/add/remove/force
# Add or remove braces on single-line 'if' statement
mod_full_brace_if = add # ignore/add/remove/force
# Don't remove braces around statements that span N newlines
mod_full_brace_nl = 0 # number
# Add or remove braces on single-line 'while' statement
mod_full_brace_while = add # ignore/add/remove/force
# Add or remove unnecessary paren on 'return' statement
mod_paren_on_return = remove # ignore/add/remove/force
# Whether to change optional semicolons to real semicolons
mod_pawn_semicolon = false # false/true
#
# Comment modifications
#
# Whether to group cpp-comments that look like they are in a block
cmt_cpp_group = false # false/true
# Whether to put an empty '/*' on the first line of the combined cpp-comment
cmt_cpp_nl_start = false # false/true
# Whether to put a newline before the closing '*/' of the combined cpp-comment
cmt_cpp_nl_end = false # false/true
# Whether to change cpp-comments into c-comments
cmt_cpp_to_c = true # false/true
# Whether to put a star on subsequent comment lines
cmt_star_cont = true # false/true
#
# Preprocessor options
#
# Add or remove indent of preprocessor directives
pp_indent = ignore # ignore/add/remove/force
# Add or remove space between # and, say, define
pp_space = ignore # ignore/add/remove/force

@ -0,0 +1,142 @@
AC_DEFUN([AX_PATH_LIB_PCRE],[dnl
AC_MSG_CHECKING([lib pcre])
AC_ARG_WITH(pcre,
[ --with-pcre[[=prefix]] compile xmlpcre part (via libpcre check)],,
with_pcre="yes")
if test ".$with_pcre" = ".no" ; then
AC_MSG_RESULT([disabled])
m4_ifval($2,$2)
else
AC_MSG_RESULT([(testing)])
AC_CHECK_LIB(pcre, pcre_study)
AC_CHECK_HEADERS(pcre.h pcre/pcre.h)
if test "$ac_cv_lib_pcre_pcre_study" = "yes" ; then
PCRE_LIBS="-lpcre"
AC_MSG_CHECKING([lib pcre])
AC_MSG_RESULT([$PCRE_LIBS])
m4_ifval($1,$1)
else
OLDLDFLAGS="$LDFLAGS" ; LDFLAGS="$LDFLAGS -L$with_pcre/lib"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$with_pcre/include"
AC_CHECK_LIB(pcre, pcre_compile)
CPPFLAGS="$OLDCPPFLAGS"
LDFLAGS="$OLDLDFLAGS"
if test "$ac_cv_lib_pcre_pcre_compile" = "yes" ; then
AC_MSG_RESULT(.setting PCRE_LIBS -L$with_pcre/lib -lpcre)
PCRE_LIBS="-L$with_pcre/lib -lpcre"
test -d "$with_pcre/include" && PCRE_CFLAGS="-I$with_pcre/include"
AC_MSG_CHECKING([lib pcre])
AC_MSG_RESULT([$PCRE_LIBS])
m4_ifval($1,$1)
else
AC_MSG_CHECKING([lib pcre])
AC_MSG_RESULT([no, (WARNING)])
m4_ifval($2,$2)
fi
fi
fi
AC_SUBST([PCRE_LIBS])
AC_SUBST([PCRE_CFLAGS])
])
AC_DEFUN([AX_PATH_LIB_READLINE],[dnl
AC_MSG_CHECKING([lib readline])
AC_ARG_WITH(readline,
[ --with-readline[[=prefix]] compile xmlreadline part (via libreadline check)],,
with_readline="yes")
if test ".$with_readline" = ".no" ; then
AC_MSG_RESULT([disabled])
m4_ifval($2,$2)
else
if test ".$with_readline" = ".yes"; then
OLD_LIBS="$LIBS"
AC_CHECK_LIB(readline, readline, [], [], [-ltermcap])
LIBS="$OLD_LIBS"
if test "$ac_cv_lib_readline_readline" = "yes"; then
READLINE_LIBS="-lreadline"
AC_MSG_CHECKING([lib readline])
AC_MSG_RESULT([$READLINE_LIBS])
m4_ifval($1,$1)
else
AC_MSG_CHECKING([lib readline])
AC_MSG_RESULT([no, (WARNING)])
m4_ifval($2,$2)
fi
else
LIBS="$LIBS $with_readline/lib/libreadline.a"
OLDCPPFLAGS="$CPPFLAGS" ; CPPFLAGS="$CPPFLAGS -I$with_readline/include"
AC_CHECK_HEADERS(readline.h readline/readline.h)
CPPFLAGS="$OLDCPPFLAGS"
READLINE_LIBS="$with_readline/lib/libreadline.a"
test -d "$with_readline/include" && READLINE_CFLAGS="-I$with_readline/include"
AC_MSG_CHECKING([lib readline])
AC_MSG_RESULT([$READLINE_LIBS])
m4_ifval($1,$1)
fi
fi
AC_SUBST([READLINE_LIBS])
AC_SUBST([READLINE_CFLAGS])
])
AC_DEFUN([MP_WITH_CURSES],
[AC_ARG_WITH(ncurses, [ --with-ncurses Force the use of ncurses over curses],,)
mp_save_LIBS="$LIBS"
CURSES_LIB=""
if test "$with_ncurses" != yes
then
AC_CACHE_CHECK([for working curses], mp_cv_curses,
[LIBS="$LIBS -lcurses"
AC_TRY_LINK(
[#include <curses.h>],
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
mp_cv_curses=yes, mp_cv_curses=no)])
if test "$mp_cv_curses" = yes
then
AC_DEFINE(HAVE_CURSES_H, [], [curses library])
CURSES_LIB="-lcurses"
fi
fi
if test ! "$CURSES_LIB"
then
AC_CACHE_CHECK([for working ncurses], mp_cv_ncurses,
[LIBS="$mp_save_LIBS -lncurses"
AC_TRY_LINK(
[#include <ncurses.h>],
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
mp_cv_ncurses=yes, mp_cv_ncurses=no)])
if test "$mp_cv_ncurses" = yes
then
AC_DEFINE(HAVE_NCURSES_H, [], [curses library])
CURSES_LIB="-lncurses"
fi
fi
LIBS="$mp_save_LIBS"
AC_SUBST(CURSES_LIB)
])dnl
AC_DEFUN([AX_PATH_LIB_SOCI],[dnl
AC_MSG_CHECKING([lib soci])
AC_ARG_WITH(soci,
[ --with-soci[[=prefix]] compile soci part (via libsoci check)],,
with_soci="yes")
if test ".$with_soci" = ".no" ; then
AC_MSG_RESULT([disabled])
m4_ifval($2,$2)
else
AC_MSG_RESULT([(testing)])
AC_LANG_PUSH([C++])
AC_CHECK_HEADERS(soci/soci.h)
AC_LANG_POP([C++])
if test "$ac_cv_header_soci_soci_h" = "yes" ; then
if test ".$with_soci" == ".yes"; then
with_soci="/usr/local/include"
fi
SOCI_CXXFLAGS="-I${with_soci}/soci -I${with_soci}/soci/sqlite3"
SOCI_LIBS="-lsoci_sqlite3-gcc-3_0 -lsoci_core-gcc-3_0"
fi
fi
AC_SUBST([SOCI_LIBS])
AC_SUBST([SOCI_CXXFLAGS])
])

@ -0,0 +1,336 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997, 1999, 2000, 2002 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
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
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]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing 0.4 - 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 missing on your system. 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 missing on your system. 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 missing on your system. 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 missing on your system. 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, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them.
You can get \`$1Help2man' 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' is missing on your system. 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 missing on your system. 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 missing on your system. 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 missing on your system. 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 you do not seem to have it handy on your
system. 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 prerequirements 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

@ -0,0 +1,99 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case "${1}" in
-h | --help | --h* ) # -h for help
echo "${usage}" 1>&2; exit 0 ;;
-m ) # -m PERM arg
shift
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
dirmode="${1}"
shift ;;
-- ) shift; break ;; # stop option processing
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
* ) break ;; # first non-opt arg
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi ;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
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: 3
# End:
# mkinstalldirs ends here

@ -0,0 +1,82 @@
bin_PROGRAMS = lnav
noinst_LIBRARIES = libdiag.a
if HAVE_OBJCOPY
help.txt.term: help.txt
cat $< > $@
/bin/echo -en '\000' >> $@
help.o: help.txt.term
objcopy -I binary -O elf64-x86-64 -Bi386 \
--redefine-sym _binary_help_txt_term_start=help_text_start \
--redefine-sym _binary_help_txt_term_end=help_text_end \
--redefine-sym _binary_help_txt_term_size=help_text_size \
$< $@
HELP_O = help.o
HELP_SRC =
else
HELP_O =
HELP_SRC = help.cc
endif
AM_LDFLAGS = \
$(SQLITE3_LDFLAGS)
AM_CPPFLAGS = \
$(SQLITE3_CFLAGS) \
$(SOCI_CXXFLAGS)
LDADD = \
libdiag.a \
$(READLINE_LIBS) \
$(CURSES_LIB) \
$(HELP_O) \
$(SOCI_LIBS) \
/usr/lib/libsqlite3.a \
-ldl \
-lz \
-lpcrecpp
noinst_HEADERS = \
bookmarks.hh \
grep_proc.hh \
help.hh \
hist_source.hh \
line_buffer.hh \
listview_curses.hh \
log_format.hh \
logfile.hh \
logfile_sub_source.hh \
readline_curses.hh \
statusview_curses.hh \
piper_proc.hh \
textview_curses.hh \
view_curses.hh \
vt52_curses.hh \
log_vtab_impl.hh
libdiag_a_SOURCES = \
bookmarks.cc \
grep_proc.cc \
hist_source.cc \
line_buffer.cc \
listview_curses.cc \
log_format.cc \
logfile.cc \
logfile_sub_source.cc \
readline_curses.cc \
statusview_curses.cc \
piper_proc.cc \
textview_curses.cc \
view_curses.cc \
vt52_curses.cc \
log_vtab_impl.cc
lnav_SOURCES = lnav.cc $(HELP_SRC)
uncrusty:
(cd $(srcdir) && uncrustify -c ../lnav.cfg --replace $(SOURCES) \
$(HEADERS))

@ -0,0 +1,580 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 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@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@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@
bin_PROGRAMS = lnav$(EXEEXT)
subdir = src
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_sqlite3.m4 \
$(top_srcdir)/lnav.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
libdiag_a_AR = $(AR) $(ARFLAGS)
libdiag_a_LIBADD =
am_libdiag_a_OBJECTS = bookmarks.$(OBJEXT) grep_proc.$(OBJEXT) \
hist_source.$(OBJEXT) line_buffer.$(OBJEXT) \
listview_curses.$(OBJEXT) log_format.$(OBJEXT) \
logfile.$(OBJEXT) logfile_sub_source.$(OBJEXT) \
readline_curses.$(OBJEXT) statusview_curses.$(OBJEXT) \
piper_proc.$(OBJEXT) textview_curses.$(OBJEXT) \
view_curses.$(OBJEXT) vt52_curses.$(OBJEXT) \
log_vtab_impl.$(OBJEXT)
libdiag_a_OBJECTS = $(am_libdiag_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am__lnav_SOURCES_DIST = lnav.cc help.cc
@HAVE_OBJCOPY_FALSE@am__objects_1 = help.$(OBJEXT)
am_lnav_OBJECTS = lnav.$(OBJEXT) $(am__objects_1)
lnav_OBJECTS = $(am_lnav_OBJECTS)
lnav_LDADD = $(LDADD)
am__DEPENDENCIES_1 =
@HAVE_OBJCOPY_TRUE@am__DEPENDENCIES_2 = help.o
lnav_DEPENDENCIES = libdiag.a $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_1) /usr/lib/libsqlite3.a
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(libdiag_a_SOURCES) $(lnav_SOURCES)
DIST_SOURCES = $(libdiag_a_SOURCES) $(am__lnav_SOURCES_DIST)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CFLAGS_PG = @CFLAGS_PG@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIB = @CURSES_LIB@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCRE_CFLAGS = @PCRE_CFLAGS@
PCRE_LIBS = @PCRE_LIBS@
RANLIB = @RANLIB@
READLINE_CFLAGS = @READLINE_CFLAGS@
READLINE_LIBS = @READLINE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCI_CXXFLAGS = @SOCI_CXXFLAGS@
SOCI_LIBS = @SOCI_LIBS@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LDFLAGS = @SQLITE3_LDFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
SQLITE3_VERSION = @SQLITE3_VERSION@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
abssrcdir = @abssrcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
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@
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@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
noinst_LIBRARIES = libdiag.a
@HAVE_OBJCOPY_FALSE@HELP_O =
@HAVE_OBJCOPY_TRUE@HELP_O = help.o
@HAVE_OBJCOPY_FALSE@HELP_SRC = help.cc
@HAVE_OBJCOPY_TRUE@HELP_SRC =
AM_LDFLAGS = \
$(SQLITE3_LDFLAGS)
AM_CPPFLAGS = \
$(SQLITE3_CFLAGS) \
$(SOCI_CXXFLAGS)
LDADD = \
libdiag.a \
$(READLINE_LIBS) \
$(CURSES_LIB) \
$(HELP_O) \
$(SOCI_LIBS) \
/usr/lib/libsqlite3.a \
-ldl \
-lz \
-lpcrecpp
noinst_HEADERS = \
bookmarks.hh \
grep_proc.hh \
help.hh \
hist_source.hh \
line_buffer.hh \
listview_curses.hh \
log_format.hh \
logfile.hh \
logfile_sub_source.hh \
readline_curses.hh \
statusview_curses.hh \
piper_proc.hh \
textview_curses.hh \
view_curses.hh \
vt52_curses.hh \
log_vtab_impl.hh
libdiag_a_SOURCES = \
bookmarks.cc \
grep_proc.cc \
hist_source.cc \
line_buffer.cc \
listview_curses.cc \
log_format.cc \
logfile.cc \
logfile_sub_source.cc \
readline_curses.cc \
statusview_curses.cc \
piper_proc.cc \
textview_curses.cc \
view_curses.cc \
vt52_curses.cc \
log_vtab_impl.cc
lnav_SOURCES = lnav.cc $(HELP_SRC)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .cc .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign src/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: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/config.h
$(srcdir)/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libdiag.a: $(libdiag_a_OBJECTS) $(libdiag_a_DEPENDENCIES)
-rm -f libdiag.a
$(libdiag_a_AR) libdiag.a $(libdiag_a_OBJECTS) $(libdiag_a_LIBADD)
$(RANLIB) libdiag.a
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
lnav$(EXEEXT): $(lnav_OBJECTS) $(lnav_DEPENDENCIES)
@rm -f lnav$(EXEEXT)
$(CXXLINK) $(lnav_OBJECTS) $(lnav_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bookmarks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grep_proc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hist_source.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/line_buffer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/listview_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lnav.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log_format.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log_vtab_impl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile_sub_source.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/piper_proc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readline_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/statusview_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textview_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vt52_curses.Po@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cc.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
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; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(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; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
list='$(SOURCES) $(HEADERS) config.h.in $(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)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& 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 $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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) $(PROGRAMS) $(HEADERS) config.h
installdirs:
for dir in "$(DESTDIR)$(bindir)"; 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)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-exec-am: install-binPROGRAMS
install-html: install-html-am
install-info: install-info-am
install-man:
install-pdf: install-pdf-am
install-ps: 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
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-binPROGRAMS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
clean-generic clean-noinstLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-hdr \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-binPROGRAMS 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 pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-binPROGRAMS
@HAVE_OBJCOPY_TRUE@help.txt.term: help.txt
@HAVE_OBJCOPY_TRUE@ cat $< > $@
@HAVE_OBJCOPY_TRUE@ /bin/echo -en '\000' >> $@
@HAVE_OBJCOPY_TRUE@help.o: help.txt.term
@HAVE_OBJCOPY_TRUE@ objcopy -I binary -O elf64-x86-64 -Bi386 \
@HAVE_OBJCOPY_TRUE@ --redefine-sym _binary_help_txt_term_start=help_text_start \
@HAVE_OBJCOPY_TRUE@ --redefine-sym _binary_help_txt_term_end=help_text_end \
@HAVE_OBJCOPY_TRUE@ --redefine-sym _binary_help_txt_term_size=help_text_size \
@HAVE_OBJCOPY_TRUE@ $< $@
uncrusty:
(cd $(srcdir) && uncrustify -c ../lnav.cfg --replace $(SOURCES) \
$(HEADERS))
# 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:

@ -0,0 +1,169 @@
/**
* @file auto_fd.hh
*/
#ifndef __auto_fd_hh
#define __auto_fd_hh
#include <assert.h>
#include <unistd.h>
#include <sys/select.h>
#include <new>
#include <exception>
/**
* Resource management class for file descriptors.
*
* @see auto_ptr
*/
class auto_fd {
public:
/**
* Wrapper for the posix pipe(2) function that stores the file descriptor
* results in an auto_fd array.
*
* @param af An array of atleast two auto_fd elements, where the first
* contains the reader end of the pipe and the second contains the writer.
* @return The result of the pipe(2) function.
*/
static int pipe(auto_fd *af)
{
int retval, fd[2];
assert(fd != NULL);
if ((retval = ::pipe(fd)) == 0) {
af[0] = fd[0];
af[1] = fd[1];
}
return(retval);
};
/**
* Construct an auto_fd to manage the given file descriptor.
*
* @param fd The file descriptor to be managed.
*/
auto_fd(int fd = -1)
: af_fd(fd)
{
assert(fd >= -1);
assert(fd < FD_SETSIZE);
};
/**
* Non-const copy constructor. Management of the file descriptor will be
* transferred from the source to this object and the source will be
* cleared.
*
* @param af The source of the file descriptor.
*/
auto_fd(auto_fd &af)
: af_fd(af.release()) { };
/**
* Const copy constructor. The file descriptor from the source will be
* dup(2)'d and the new descriptor stored in this object.
*
* @param af The source of the file descriptor.
*/
auto_fd(const auto_fd &af)
: af_fd(-1)
{
if (af.af_fd != -1 && (this->af_fd = dup(af.af_fd)) == -1) {
throw std::bad_alloc();
}
};
/**
* Destructor that will close the file descriptor managed by this object.
*/
~auto_fd() { this->reset(); };
/** @return The file descriptor as a pain integer. */
operator int(void) const { return(this->af_fd); };
/**
* Replace the current descriptor with the given one. The current
* descriptor will be closed.
*
* @param fd The file descriptor to store in this object.
* @return *this
*/
auto_fd &operator=(int fd)
{
assert(fd >= -1);
assert(fd < FD_SETSIZE);
this->reset(fd);
return(*this);
};
/**
* Transfer management of the given file descriptor to this object.
*
* @param af The old manager of the file descriptor.
* @return *this
*/
auto_fd &operator=(auto_fd &af)
{
this->reset(af.release());
return(*this);
};
/**
* Return a pointer that can be passed to functions that require an out
* parameter for file descriptors (e.g. openpty).
*
* @return A pointer to the internal integer.
*/
int *out(void)
{
this->reset();
return(&this->af_fd);
};
/**
* Stop managing the file descriptor in this object and return its value.
*
* @return The file descriptor.
*/
int release(void)
{
int retval = this->af_fd;
this->af_fd = -1;
return(retval);
};
/**
* @return The file descriptor.
*/
int get(void) const { return(this->af_fd); };
/**
* Closes the current file descriptor and replaces its value with the given
* one.
*
* @param fd The new file descriptor to be managed.
*/
void reset(int fd = -1)
{
assert(fd >= -1);
assert(fd < FD_SETSIZE);
if (this->af_fd != fd) {
if (this->af_fd != -1) {
close(this->af_fd);
}
this->af_fd = fd;
}
};
private:
int af_fd; /*< The managed file descriptor. */
};
#endif

@ -0,0 +1,68 @@
/**
* @file auto_mem.hh
*/
#ifndef __auto_mem_hh
#define __auto_mem_hh
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <exception>
/**
* Resource management class for memory allocated by a custom allocator.
*
* @param T The object type.
* @param auto_free The function to call to free the managed object.
*/
template<class T, void (*auto_free)(void *) = free>
class auto_mem {
public:
auto_mem(T *ptr = NULL) : am_ptr(ptr) { };
auto_mem(auto_mem &am) : am_ptr(am.release()) { };
~auto_mem() { this->reset(); };
operator T *(void) const { return this->am_ptr; };
auto_mem &operator=(T *ptr) {
this->reset(ptr);
return *this;
};
auto_mem &operator=(auto_mem &am) {
this->reset(am.release());
return *this;
};
T *release(void) {
T *retval = this->am_ptr;
this->am_ptr = NULL;
return retval;
};
T *in(void) { return this->am_ptr; };
T **out(void) {
this->reset();
return &this->am_ptr;
};
void reset(T *ptr = NULL) {
if (this->am_ptr != ptr) {
auto_free(this->am_ptr);
this->am_ptr = ptr;
}
};
private:
T *am_ptr;
};
#endif

@ -0,0 +1,57 @@
#ifndef __auto_temp_file_hh
#define __auto_temp_file_hh
#include <unistd.h>
#include <string>
class auto_temp_file {
public:
auto_temp_file(const char *cpat = NULL) {
this->reset(cpat);
};
auto_temp_file(auto_temp_file &atf) : atf_name(atf.release()) { };
~auto_temp_file() { this->reset(); };
operator std::string(void) const { return this->atf_name; };
auto_temp_file &operator=(const char *cpat) {
this->reset(cpat);
return *this;
};
auto_temp_file &operator=(auto_temp_file &atf) {
this->reset();
this->atf_name = atf.release();
return *this;
};
std::string release(void) {
std::string retval = this->atf_name;
this->atf_name.clear();
return retval;
};
void reset(const char *cpat = NULL) {
if (!this->atf_name.empty()) {
unlink(this->atf_name.c_str());
this->atf_name.clear();
}
if (cpat != NULL) {
char *pat = (char *)alloca(strlen(cpat) + 1); /* XXX */
strcpy(pat, cpat);
mktemp(pat);
this->atf_name = pat;
}
};
private:
std::string atf_name;
};
#endif

@ -0,0 +1,42 @@
/**
* @file bookmarks.cc
*/
#include "bookmarks.hh"
vis_line_t bookmark_vector::next(vis_line_t start)
{
std::vector<vis_line_t>::iterator ub;
vis_line_t retval(-1);
assert(start >= -1);
ub = upper_bound(this->begin(), this->end(), start);
if (ub != this->end()) {
retval = *ub;
}
assert(retval == -1 || start < retval);
return retval;
}
vis_line_t bookmark_vector::prev(vis_line_t start)
{
std::vector<vis_line_t>::iterator lb;
vis_line_t retval(-1);
assert(start >= 0);
lb = lower_bound(this->begin(), this->end(), start);
if (lb != this->begin()) {
lb -= 1;
retval = *lb;
}
assert(retval < start);
return retval;
}

@ -0,0 +1,84 @@
/**
* @file bookmarks.hh
*/
#ifndef __bookmarks_hh
#define __bookmarks_hh
#include <assert.h>
#include <map>
#include <vector>
#include <algorithm>
#include "listview_curses.hh"
/**
* Extension of the STL vector that is used to store bookmarks for
* files being viewed, where a bookmark is just a particular line in
* the file(s). The value-added over the standard vector are some
* methods for doing content-wise iteration. In other words, given a
* value that may or may not be in the vector, find the next or
* previous value that is in the vector.
*
* @note The vector is expected to be sorted.
*/
class bookmark_vector
: public std::vector<vis_line_t> {
public:
/**
* Insert a bookmark into this vector, but only if it is not already in the
* vector.
*
* @param vl The line to bookmark.
*/
iterator insert_once(vis_line_t vl)
{
iterator lb, retval;
assert(vl >= 0);
lb = std::lower_bound(this->begin(), this->end(), vl);
if (lb == this->end() || *lb != vl) {
this->insert(lb, vl);
retval = this->end();
}
else {
retval = lb;
}
return retval;
};
/**
* @param start The value to start the search for the next bookmark.
* @return The next bookmark value in the vector or -1 if there are
* no more remaining bookmarks. If the 'start' value is a bookmark,
* the next bookmark is returned. If the 'start' value is not a
* bookmark, the next highest value in the vector is returned.
*/
vis_line_t next(vis_line_t start);
/**
* @param start The value to start the search for the previous
* bookmark.
* @return The previous bookmark value in the vector or -1 if there
* are no more prior bookmarks.
* @see next
*/
vis_line_t prev(vis_line_t start);
};
/**
* Dummy type whose instances are used to distinguish between
* bookmarks maintained by different source modules.
*/
class bookmark_type_t { };
/**
* Map of bookmark types to bookmark vectors.
*/
typedef std::map<bookmark_type_t *, bookmark_vector> bookmarks;
#endif

@ -0,0 +1,203 @@
#ifndef _bottom_status_source_hh
#define _bottom_status_source_hh
#include <string>
class bottom_status_source
: public status_data_source,
public grep_proc_control
{
public:
typedef listview_curses::action::mem_functor_t<
bottom_status_source> lv_functor_t;
typedef textview_curses::action::mem_functor_t<
bottom_status_source> tv_functor_t;
typedef enum {
BSF_LINE_NUMBER,
BSF_PERCENT,
BSF_HITS,
BSF_WARNINGS,
BSF_ERRORS,
BSF_FILTERED,
BSF_LOADING,
BSF__MAX
} field_t;
bottom_status_source()
: bss_error(80, view_colors::VCR_ALERT_STATUS),
line_number_wire(*this, &bottom_status_source::update_line_number),
percent_wire(*this, &bottom_status_source::update_percent),
marks_wire(*this, &bottom_status_source::update_marks),
hits_wire(*this, &bottom_status_source::update_hits),
bss_hit_spinner(0),
bss_load_percent(0) {
this->bss_fields[BSF_LINE_NUMBER].set_width(8);
this->bss_fields[BSF_PERCENT].set_width(4);
this->bss_fields[BSF_HITS].set_width(16);
this->bss_fields[BSF_HITS].set_cylon(true);
this->bss_fields[BSF_WARNINGS].set_width(10);
this->bss_fields[BSF_ERRORS].set_width(10);
this->bss_fields[BSF_ERRORS].set_role(view_colors::VCR_ALERT_STATUS);
this->bss_fields[BSF_FILTERED].set_width(14);
this->bss_fields[BSF_LOADING].set_width(13);
this->bss_fields[BSF_LOADING].set_cylon(true);
this->bss_fields[BSF_LOADING].right_justify(true);
};
virtual ~bottom_status_source() { };
lv_functor_t line_number_wire;
lv_functor_t percent_wire;
lv_functor_t marks_wire;
tv_functor_t hits_wire;
status_field &get_field(field_t id) { return this->bss_fields[id]; };
void grep_error(std::string msg) {
this->bss_error.set_value(msg);
};
size_t statusview_fields(void) {
size_t retval;
if (this->bss_error.empty())
retval = BSF__MAX;
else
retval = 1;
return retval;
};
status_field &statusview_value_for_field(int field) {
if (this->bss_error.empty())
return this->get_field((field_t)field);
else
return this->bss_error;
};
void update_line_number(listview_curses *lc) {
status_field &sf = this->bss_fields[BSF_LINE_NUMBER];
if (lc->get_inner_height() == 0)
sf.set_value("L0");
else
sf.set_value("L%d", (int)lc->get_top());
};
void update_percent(listview_curses *lc) {
status_field &sf = this->bss_fields[BSF_PERCENT];
vis_line_t top = lc->get_top();
vis_line_t bottom, height;
unsigned long width;
double percent;
lc->get_dimensions(height, width);
if (lc->get_inner_height() > 0) {
bottom = std::min(top + height - vis_line_t(1),
vis_line_t(lc->get_inner_height() - 1));
percent = (double)(bottom + 1);
percent /= (double)lc->get_inner_height();
percent *= 100.0;
}
else {
percent = 0.0;
}
sf.set_value("%3d%%", (int)percent);
};
void update_marks(listview_curses *lc) {
textview_curses *tc = static_cast<textview_curses *>(lc);
status_field &sfw = this->bss_fields[BSF_WARNINGS];
status_field &sfe = this->bss_fields[BSF_ERRORS];
bookmarks &bm = tc->get_bookmarks();
unsigned long width;
vis_line_t height;
tc->get_dimensions(height, width);
if (bm.find(&logfile_sub_source::BM_WARNINGS) != bm.end()) {
bookmark_vector &bv = bm[&logfile_sub_source::BM_WARNINGS];
bookmark_vector::iterator iter;
iter = lower_bound(bv.begin(), bv.end(), tc->get_top() + height);
sfw.set_value("%9dW", distance(iter, bv.end()));
}
else {
sfw.clear();
}
if (bm.find(&logfile_sub_source::BM_ERRORS) != bm.end()) {
bookmark_vector &bv = bm[&logfile_sub_source::BM_ERRORS];
bookmark_vector::iterator iter;
iter = lower_bound(bv.begin(), bv.end(), tc->get_top() + height);
sfe.set_value("%9dE", distance(iter, bv.end()));
}
else {
sfe.clear();
}
};
void update_hits(textview_curses *tc) {
status_field &sf = this->bss_fields[BSF_HITS];
view_colors::role_t new_role;
if (tc->is_searching()) {
this->bss_hit_spinner += 1;
if (this->bss_hit_spinner % 2)
new_role = view_colors::VCR_ACTIVE_STATUS;
else
new_role = view_colors::VCR_ACTIVE_STATUS2;
sf.set_cylon(true);
}
else {
new_role = view_colors::VCR_STATUS;
sf.set_cylon(false);
}
sf.set_role(new_role);
this->bss_error.clear();
sf.set_value("%9d hits", tc->get_match_count());
};
void update_loading(off_t off, size_t total) {
status_field &sf = this->bss_fields[BSF_LOADING];
if (off == total) {
sf.set_role(view_colors::VCR_STATUS);
sf.clear();
}
else {
int pct = ((double)off / (double)total) * 100.0;
if (this->bss_load_percent != pct) {
this->bss_load_percent = pct;
sf.set_role(view_colors::VCR_ACTIVE_STATUS2);
sf.set_value(" Loading %2d%% ", pct);
}
}
};
void update_filtered(logfile_sub_source &lss) {
status_field &sf = this->bss_fields[BSF_FILTERED];
if (lss.get_filtered_count() == 0)
sf.clear();
else
sf.set_value("%d Not Shown", lss.get_filtered_count());
};
private:
status_field bss_error;
status_field bss_fields[BSF__MAX];
int bss_hit_spinner;
int bss_load_percent;
};
#endif

@ -0,0 +1,103 @@
/* src/config.h.in. Generated from configure.in by autoheader. */
/* curses library */
#undef HAVE_CURSES_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `pcre' library (-lpcre). */
#undef HAVE_LIBPCRE
/* Define to 1 if you have the `readline' library (-lreadline). */
#undef HAVE_LIBREADLINE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* curses library */
#undef HAVE_NCURSES_H
/* Define to 1 if you have the <pcre.h> header file. */
#undef HAVE_PCRE_H
/* Define to 1 if you have the <pcre/pcre.h> header file. */
#undef HAVE_PCRE_PCRE_H
/* Define to 1 if you have the <pty.h> header file. */
#undef HAVE_PTY_H
/* Define to 1 if you have the <readline.h> header file. */
#undef HAVE_READLINE_H
/* Define to 1 if you have the <readline/readline.h> header file. */
#undef HAVE_READLINE_READLINE_H
/* Define to 1 if you have the <soci/soci.h> header file. */
#undef HAVE_SOCI_SOCI_H
/* sqlite3 */
#undef HAVE_SQLITE3
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <util.h> header file. */
#undef HAVE_UTIL_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Needed for the 'timezone' variable */
#undef _APPLE_C_SOURCE
/* Need pread */
#undef _BSD_SOURCE
/* Need pread */
#undef _XOPEN_SOURCE

@ -0,0 +1,48 @@
#ifndef __db_sub_source_hh
#define __db_sub_source_hh
#include <string>
#include <vector>
#include "hist_source.hh"
class db_label_source : public hist_source::label_source {
public:
db_label_source() { };
~db_label_source() { };
void hist_label_for_bucket(int bucket_start_value,
const hist_source::bucket_t &bucket,
std::string &label_out) {
/*
* start_value is the result rowid, each bucket type is a column value
* label_out should be the raw text output.
*/
label_out.clear();
if (bucket_start_value >= this->dls_rows.size())
return;
for (int lpc = 0; lpc < this->dls_rows[bucket_start_value].size(); lpc++) {
label_out.append(this->dls_column_sizes[lpc] - this->dls_rows[bucket_start_value][lpc].length(), ' ');
label_out.append(this->dls_rows[bucket_start_value][lpc]);
}
};
void push_column(const char *colstr) {
int index = this->dls_rows.back().size();
this->dls_rows.back().push_back(colstr);
if (this->dls_rows.back().size() > this->dls_column_sizes.size()) {
this->dls_column_sizes.push_back(1);
}
this->dls_column_sizes[index] =
std::max(this->dls_column_sizes[index], strlen(colstr) + 1);
};
std::vector< std::vector< std::string > > dls_rows;
std::vector< size_t > dls_column_sizes;
};
#endif

@ -0,0 +1,339 @@
/**
* @file grep_proc.cc
*/
#include "config.h"
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "grep_proc.hh"
#include "time_T.hh"
using namespace std;
grep_proc::grep_proc(pcre *code,
grep_proc_source &gps,
int &maxfd,
fd_set &readfds)
: gp_pcre(code),
gp_code(code),
gp_source(gps),
gp_pipe_offset(0),
gp_child(-1),
gp_child_started(false),
gp_maxfd(maxfd),
gp_readfds(readfds),
gp_last_line(0),
gp_sink(NULL),
gp_control(NULL)
{
const char *errptr;
this->gp_code_extra = pcre_study(code, 0, &errptr);
assert(this->invariant());
}
grep_proc::~grep_proc()
{
this->cleanup();
}
void grep_proc::handle_match(int line,
string &line_value,
int off,
int *matches,
int count)
{
int lpc;
if (off == 0) {
fprintf(stdout, "%d\n", line);
}
fprintf(stdout, "[%d:%d]\n", matches[0], matches[1]);
for (lpc = 1; lpc < count; lpc++) {
fprintf(stdout,
"(%d:%d)",
matches[lpc * 2],
matches[lpc * 2 + 1]);
fwrite(&(line_value.c_str()[matches[lpc * 2]]),
1,
matches[lpc * 2 + 1] -
matches[lpc * 2],
stdout);
fputc('\n', stdout);
}
}
void grep_proc::start(void)
{
assert(this->invariant());
if (this->gp_child_started || this->gp_queue.empty()) {
return;
}
auto_fd out_fd[2], err_fd[2];
/* Get ahold of some pipes for stdout and stderr. */
if (auto_fd::pipe(out_fd) < 0) {
throw error(errno);
}
if (auto_fd::pipe(err_fd) < 0) {
throw error(errno);
}
if ((this->gp_child = fork()) < 0) {
throw error(errno);
}
if (this->gp_child != 0) {
fcntl(out_fd[0], F_SETFL, O_NONBLOCK);
fcntl(out_fd[0], F_SETFD, 1);
this->gp_line_buffer.set_fd(out_fd[0]);
fcntl(err_fd[0], F_SETFL, O_NONBLOCK);
fcntl(err_fd[0], F_SETFD, 1);
this->gp_err_pipe = err_fd[0];
this->gp_child_started = true;
FD_SET(this->gp_line_buffer.get_fd(), &this->gp_readfds);
FD_SET(this->gp_err_pipe, &this->gp_readfds);
this->gp_maxfd = std::max(this->gp_maxfd,
std::max(this->gp_line_buffer.get_fd(),
this->gp_err_pipe.get()));
this->gp_queue.clear();
return;
}
/* In the child... */
/*
* First, restore the default signal handlers so we don't hang around
* forever if there is a problem.
*/
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
/* Get rid of stdin, then */
close(STDIN_FILENO);
open("/dev/null", O_RDONLY);
/* ... wire up the pipes. */
dup2(out_fd[1].release(), STDOUT_FILENO);
/* dup2(err_fd[1].release(), STDERR_FILENO); */
this->child_init();
char outbuf[BUFSIZ * 2];
string line_value;
stdout = fdopen(STDOUT_FILENO, "w");
/* Make sure buffering is on, not sure of the state in the parent. */
if (setvbuf(stdout, outbuf, _IOFBF, BUFSIZ * 2) < 0) {
perror("setvbuf");
}
line_value.reserve(BUFSIZ * 2);
while (!this->gp_queue.empty()) {
grep_line_t start_line = this->gp_queue.front().first;
grep_line_t stop_line = this->gp_queue.front().second;
bool done = false, got_first_hit = false;
int line;
this->gp_queue.pop_front();
if (start_line == -1) {
start_line = this->gp_last_line;
}
for (line = start_line;
(stop_line == -1 || line < stop_line) && !done;
line++) {
line_value.clear();
done = !this->gp_source.grep_value_for_line(line, line_value);
if (!done) {
pcre_context_static<10> pc;
pcre_input pi(line_value);
while (this->gp_pcre.match(pc, pi)) {
pcre_context::iterator pc_iter;
pcre_context::match_t *m;
if (pi.pi_offset == 0) {
fprintf(stdout, "%d\n", line);
}
m = pc.all();
fprintf(stdout, "[%d:%d]\n", m->m_begin, m->m_end);
for (pc_iter = pc.begin(); pc_iter != pc.end(); pc_iter++) {
fprintf(stdout,
"(%d:%d)",
pc_iter->m_begin,
pc_iter->m_end);
fwrite(pi.get_substr(pc_iter),
1,
pc_iter->length(),
stdout);
fputc('\n', stdout);
}
}
}
if (((line + 1) % 10000) == 0) {
/* Periodically flush the buffer so the parent sees progress */
this->child_batch();
}
}
fprintf(stdout, "%d\n", line - 1);
this->child_term();
}
exit(0);
}
void grep_proc::cleanup(void)
{
if (this->gp_child != -1 && this->gp_child != 0) {
int status;
kill(this->gp_child, SIGTERM);
while (waitpid(this->gp_child, &status, 0) < 0 && (errno == EINTR)) {
;
}
assert(!WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT);
this->gp_child = -1;
this->gp_child_started = false;
if (this->gp_sink) {
this->gp_sink->grep_end(*this);
}
}
if (this->gp_err_pipe != -1) {
FD_CLR(this->gp_err_pipe, &this->gp_readfds);
this->gp_err_pipe.reset();
}
if (this->gp_line_buffer.get_fd() != -1) {
FD_CLR(this->gp_line_buffer.get_fd(), &this->gp_readfds);
}
this->gp_pipe_offset = 0;
this->gp_line_buffer.reset();
assert(this->invariant());
if (!this->gp_queue.empty()) {
this->start();
}
}
void grep_proc::dispatch_line(char *line)
{
int start, end, capture_start;
assert(line != NULL);
if (sscanf(line, "%d", this->gp_last_line.out()) == 1) {
/* Starting a new line with matches. */
assert(this->gp_last_line >= 0);
}
else if (sscanf(line, "[%d:%d]", &start, &end) == 2) {
assert(start >= 0);
assert(end >= 0);
/* Pass the match offsets to the sink delegate. */
if (this->gp_sink != NULL) {
this->gp_sink->grep_match(*this, this->gp_last_line, start, end);
}
}
else if (sscanf(line, "(%d:%d)%n", &start, &end, &capture_start) == 2) {
assert(start >= 0);
assert(end >= 0);
/* Pass the match offsets to the sink delegate. */
if (this->gp_sink != NULL) {
this->gp_sink->grep_capture(*this,
this->gp_last_line,
start,
end,
&line[capture_start]);
}
}
else {
fprintf(stderr, "bad line from child -- %s\n", line);
}
}
void grep_proc::check_fd_set(fd_set &ready_fds)
{
assert(this->invariant());
if (this->gp_err_pipe != -1 && FD_ISSET(this->gp_err_pipe, &ready_fds)) {
char buffer[1024 + 1];
int rc;
rc = read(this->gp_err_pipe, buffer, sizeof(buffer) - 1);
if (rc > 0) {
static const char *PREFIX = ": ";
buffer[rc] = '\0';
if (strncmp(buffer, PREFIX, strlen(PREFIX)) == 0) {
char *lf;
if ((lf = strchr(buffer, '\n')) != NULL) {
*lf = '\0';
}
if (this->gp_control != NULL) {
this->gp_control->grep_error(&buffer[strlen(PREFIX)]);
}
}
}
else if (rc == 0) {
FD_CLR(this->gp_err_pipe, &this->gp_readfds);
this->gp_err_pipe.reset();
}
}
if (this->gp_line_buffer.get_fd() != -1 &&
FD_ISSET(this->gp_line_buffer.get_fd(), &ready_fds)) {
try {
static const int MAX_LOOPS = 100;
int loop_count = 0;
size_t len;
char *line;
while ((loop_count < MAX_LOOPS) &&
(line = this->gp_line_buffer.read_line(this->gp_pipe_offset,
len)) != NULL) {
line[len] = '\0';
this->dispatch_line(line);
loop_count += 1;
}
if (this->gp_sink != NULL) {
this->gp_sink->grep_end_batch(*this);
}
if ((off_t) this->gp_line_buffer.get_file_size() ==
this->gp_pipe_offset) {
this->cleanup();
}
}
catch (line_buffer::error & e) {
this->cleanup();
}
}
assert(this->invariant());
}

@ -0,0 +1,268 @@
/**
* @file grep_proc.hh
*/
#ifndef __grep_proc_hh
#define __grep_proc_hh
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <assert.h>
#ifdef HAVE_PCRE_H
#include <pcre.h>
#elif HAVE_PCRE_PCRE_H
#include <pcre/pcre.h>
#endif
#include <deque>
#include <string>
#include <vector>
#include <exception>
#include "pcrepp.hh"
#include "auto_fd.hh"
#include "auto_mem.hh"
#include "strong_int.hh"
#include "line_buffer.hh"
/** Strongly-typed integer for matched line numbers. */
STRONG_INT_TYPE(int, grep_line);
class grep_proc;
/**
* Data source for lines to be searched using a grep_proc.
*/
class grep_proc_source {
public:
virtual ~grep_proc_source() { };
/**
* Get the value for a particular line in the source.
*
* @param line The line to retrieve.
* @param value_out The destination for the line value.
*/
virtual bool grep_value_for_line(int line, std::string &value_out) = 0;
virtual std::string grep_source_name(void) { return ""; };
};
class grep_proc_control {
public:
virtual ~grep_proc_control() { };
/** @param msg The error encountered while attempting the grep. */
virtual void grep_error(std::string msg) { };
};
/**
* Sink for matches produced by a grep_proc instance.
*/
class grep_proc_sink {
public:
virtual ~grep_proc_sink() { };
/** Called at the start of a new grep run. */
virtual void grep_begin(grep_proc &gp) { };
/** Called periodically between grep_begin and grep_end. */
virtual void grep_end_batch(grep_proc &gp) { };
/** Called at the end of a grep run. */
virtual void grep_end(grep_proc &gp) { };
/**
* Called when a match is found on 'line' and between [start, end).
*
* @param line The line number that matched.
* @param start The offset within the line where the match begins.
* @param end The offset of the character after the last character in the
* match.
*/
virtual void grep_match(grep_proc &gp,
grep_line_t line,
int start,
int end) = 0;
/**
* Called for each captured substring in the line.
*
* @param line The line number that matched.
* @param start The offset within the line where the capture begins.
* @param end The offset of the character after the last character in the
* capture.
* @param capture The captured substring itself.
*/
virtual void grep_capture(grep_proc &gp,
grep_line_t line,
int start,
int end,
char *capture) { };
};
/**
* "Grep" that runs in a separate process so it doesn't stall user-interaction.
* This class manages the child process and any interactions between the parent
* and child. The source data to be matched comes from the grep_proc_source
* delegate and the results are sent to the grep_proc_sink delegate in the
* parent process.
*
* Note: The "grep" executable is not actually used, instead we use the pcre(3)
* library directly.
*/
class grep_proc {
public:
class error
: public std::exception {
public:
error(int err)
: e_err(err) { };
int e_err;
};
/**
* Construct a grep_proc object. This involves compiling the regular
* expression and then forking off the child process. Note that both the
* parent and child return from this call and you must call the start()
* method immediately afterward to get things going.
*
* @param code The pcre code to run over the lines of input.
* @param gps The source of the data to match.
* @param readfds The file descriptor set for readable fds.
*/
grep_proc(pcre *code,
grep_proc_source &gps,
int &maxfd,
fd_set &readfds);
virtual ~grep_proc();
/** @return The code passed in to the constructor. */
pcre *get_code() { return this->gp_code; };
/** @param gpd The sink to send resuls to. */
void set_sink(grep_proc_sink *gpd)
{
this->gp_sink = gpd;
if (gpd != NULL) {
this->gp_sink->grep_begin(*this);
}
};
/** @param gpd The sink to send results to. */
void set_control(grep_proc_control *gpc)
{
this->gp_control = gpc;
};
/** @return The sink to send resuls to. */
grep_proc_sink *get_sink() { return this->gp_sink; };
/**
* Queue a request to search the input between the given line numbers.
*
* @param start The line number to start the search at.
* @param stop The line number to stop the search at or -1 to read until
* the end-of-file.
*/
void queue_request(grep_line_t start = grep_line_t(0),
grep_line_t stop = grep_line_t(-1))
{
assert(start != -1 || stop == -1);
assert(stop == -1 || start < stop);
this->gp_queue.push_back(std::make_pair(start, stop));
};
/**
* Start the search requests that have been queued up with queue_request.
*/
void start(void);
/**
* Check the fd_set to see if there is any new data to be processed.
*
* @param ready_rfds The set of ready-to-read file descriptors.
*/
void check_fd_set(fd_set &ready_rfds);
/** Check the invariants for this object. */
bool invariant(void)
{
assert(this->gp_code != NULL);
if (this->gp_child_started) {
assert(this->gp_child > 0);
assert(this->gp_line_buffer.get_fd() != -1);
assert(FD_ISSET(this->gp_line_buffer.get_fd(), &this->gp_readfds));
}
else {
assert(this->gp_pipe_offset == 0);
// assert(this->gp_child == -1); XXX doesnt work with static destr
assert(this->gp_line_buffer.get_fd() == -1);
}
return true;
};
protected:
/**
* Dispatch a line received from the child.
*/
void dispatch_line(char *line);
/**
* Free any resources used by the object and make sure the child has been
* terminated.
*/
void cleanup(void);
virtual void child_init(void) { };
virtual void child_batch(void) { fflush(stdout); };
virtual void child_term(void) { fflush(stdout); };
virtual void handle_match(int line,
std::string &line_value,
int off,
int *matches,
int count);
pcrepp gp_pcre;
pcre *gp_code; /*< The compiled pattern. */
auto_mem<pcre_extra> gp_code_extra; /*< Results of a pcre_study. */
grep_proc_source & gp_source; /*< The data source delegate. */
auto_fd gp_err_pipe; /*< Standard error from the child. */
line_buffer gp_line_buffer; /*< Standard out from the child. */
off_t gp_pipe_offset;
pid_t gp_child; /*<
* The child's pid or zero in the
* child.
*/
bool gp_child_started; /*< True if the child was start()'d. */
int & gp_maxfd;
fd_set & gp_readfds; /*<
* Pointer to the read fd_set so we can
* clear our file descriptors later.
*/
/** The queue of search requests. */
std::deque<std::pair<grep_line_t, grep_line_t> > gp_queue;
grep_line_t gp_last_line; /*<
* The last line number received from
* the child. For multiple matches,
* the line number is only sent once.
*/
grep_proc_sink *gp_sink; /*< The sink delegate. */
grep_proc_control *gp_control; /*< The control delegate. */
};
#endif

@ -0,0 +1,19 @@
#include "help.hh"
typedef enum {
ME_FOO,
ME_BAR,
} my_enum_t;
struct test {
int foo;
float other;
};
struct test bar;
my_enum_t blather;
static struct test baz;
const char help_text_start[] = "Bah! No objcopy :(";

@ -0,0 +1,16 @@
/**
* @file help.hh
*/
#ifndef __help_hh
#define __help_hh
extern "C" {
/**
* The help message text. The value for this comes from the "help.txt" file,
* which gets linked into the executable by the Makefile.
*/
extern const char help_text_start[];
}
#endif

@ -0,0 +1,239 @@
lnav - A fancy log file viewer
DESCRIPTION
-----------
The log file navigator, lnav, is an enhanced log file viewer that
takes advantage of any semantic information that can be gleaned from
the files being viewed, such as timestamps and log levels. Using this
extra semantic information, lnav can do things like interleaving
messages from different files, generate histograms of messages over
time, and providing hotkeys for navigating through the file. It is
hoped that these features will allow the user to quickly and
efficiently zero in on problems.
OPTIONS
-------
Lnav takes a list of files to view and/or you can use the flag
arguments to load well-known log files, such as the syslog or apache
log files. The flag arguments are:
-s Load the most recent syslog messages file. (Default)
-a Load all of the most recent log file types.
-r Load older rotated log files as well.
When using the flag arguments, lnav will look for the files relative
to the current directory and its parent directories. In other words,
if you are working within a directory that has the well-known log
files, those will be preferred over any others. As an example, if you
are anywhere in a directory tree that was archived using 'pnlog
mailto', the log files within that tree will be loaded instead of the
files used by the local machine.
Any files given on the command-line are scanned to determine their log
file format and to create an index for each line in the file. You do
not have to manually specify the log file format. The currently
supported formats are: syslog, apache, strace, tcsh history, and
generic log files with timestamps.
DISPLAY
-------
The main part of the display shows the log lines from the files
interleaved based on time-of-day. The lines are "scrubbed" to remove
redundant/extraneous parts and highlighted to emphasize other parts.
New lines are automatically loaded as they are appended to the files
and, if you are viewing the bottom of the files, lnav will scroll down
to display the new lines, much like 'tail -f'.
On color displays, the lines will be highlighted as follows:
* Errors will be colored in red;
* warnings will be yellow;
* lines in even-numbered hours have their timestamps in bold white;
* boundaries between days will be underlined; and
* various color highlights will be applied to: SQL keywords, XML
tags, file and line numbers in Java backtraces, and
quoted strings.
To give you an idea of where you are in the file spatially, the right
side of the display has a proportionally sized 'scrollbar' that
indicates your current position in the file.
Above and below the main body are status lines that display:
* the current time;
* the number of errors/warnings above and below your current
position;
* the number of search hits, which updates as more are found;
* the line number for the top line in the display; and
* the name of the file the top line was pulled from.
Finally, the last line on the display is where you can enter search
patterns and execute internal commands, such as converting a
unix-timestamp into a human-readable date.
KEY BINDINGS
------------
To help navigate through the file there are many hotkeys that should
make it easy to zero-in on a specific section of the file or scan
through the file.
? View/leave this help message.
q Quit.
home Move to the top of the file.
end Move to the end of the file.
space/pgdn Move down a page.
b/bs/pgup Move up a page.
j/cr/down-arrow Move down a line.
k/up-arrow Move up a line.
h/left-arrow Move to the left.
l/right-arrow Move to the right.
e/E Move to the next/previous error.
w/W Move to the next/previous warning.
n/N Move to the next/previous search hit.
f/F Move to the next/previous entry in a different
file.
o/O Move forward/backward 60 minutes from the current
position in the log file.
d/D Move forward/backward 24 hours from the current
position in the log file.
1-6/Shift 1-6 Move to the next/previous n'th ten minute of the
hour. For example, '4' would move to the first
log line in the fortieth minute of the current
hour in the log. And, '6' would move to the next
hour boundary.
0/Shift 0 Move to the next/previous day boundary.
m Mark/unmark the line at the top of the display.
The line will be highlighted with reverse video to
indicate that it is a user bookmark. You can use
the 'u' hotkey to iterate through marks you have
added.
M Mark/unmark all the lines between the top of the
display and the last line marked/unmarked.
J Mark/unmark the next line after the previously
marked line.
K Like 'J' except it toggles the mark on the
previous line.
c Copy the marked text to the X selection buffer.
u/U Move forward/backward through any user bookmarks
you have added using the 'm' key.
s Toggle "scrubbing" of the input file to
hide/reveal parts of the timestamp and other
excessive/redundant information in each log line.
i View/leave a histogram of the log messages over
time. The histogram counts the number of
displayed log lines for each bucket of time. The
bars are layed out horizontally with colored
segments representing the different log levels.
You can use the 'z' hotkey to change the size of
the time buckets (e.g. ten minutes, one hour, one
day).
I Switch between the log and histogram views while
keeping the time displayed at the top of each view
in sync. For example, if the top line in the log
view is "11:40", hitting 'I' will switch to the
histogram view and scrolled to display "11:00" at
the top (if the zoom level is hours).
z/Shift Z Zoom in or out one step in the histogram view.
/<regexp> Start a search for the given regular expression.
The search is live, so when there is a pause in
typing, the currently running search will be
canceled and a new one started. History is
maintained for your searches so you can rerun them
easily. If there is an error encountered while
trying to interpret the expression, the error will
be displayed in red on the status line. While the
search is active, the 'hits' field in the status
line will be green, when finished it will turn
back to black.
:<command> Execute an internal command. The commands are
listed below. History is also supported in this
context as well as tab-completion for commands and
some arguments. The result of the command
replaces the command you typed.
;<sql> Execute an SQL query. Most supported log file
formats provide a sqlite virtual table backend
that can be used in queries. See the SQL section
below for more information.
COMMANDS
--------
unix-time <secs-or-date>
Convert a unix-timestamp in seconds to a
human-readable form or vice-versa.
BEWARE OF TIMEZONE DIFFERENCES.
current-time Print the current time in human-readable form and
as a unix-timestamp.
goto <line#|N%> Go to the given line number or N percent into the
file.
highlight <regex> Highlight strings that match the given regular
expression.
filter-in <regex> Only display lines that match the given regular
expression. This command can be used multiple
times to add more lines to the display.
filter-out <regex>
Do not display lines that match the given regular
expression. This command can be used multiple
times to remove more lines from the display. If a
'filter-in' expression is also active, it takes
priority and the filter-out will remove lines that
were matched by the 'filter-in'.
disable-filter <regex>
Disable an active 'filter-in' or 'filter-out'
expression.
enable-filter <regex>
Enable a inactive 'filter-in' or 'filter-out'
expression.
graph <regex> Graph the value of numbers in the file(s) over
time. The given regular expression should capture
the number to be displayed. For example:
my stats: (\d+\.\d+)
Will graph all the "stats" values found in the
file. XXX This is still mostly a toy...
append-to <file> Append any marked lines to the given file.
write-to <file> Write any marked lines to the given file.
SQL
---
WRITE ME

@ -0,0 +1,147 @@
#include "config.h"
#include <math.h>
#include <limits.h>
#include "lnav_util.hh"
#include "hist_source.hh"
using namespace std;
hist_source::hist_source()
: hs_bucket_size(1),
hs_group_size(100),
hs_label_source(NULL),
hs_token_bucket(NULL)
{ }
void hist_source::text_value_for_line(textview_curses &tc,
int row,
std::string &value_out,
bool no_scrub)
{
int grow = row / (this->buckets_per_group() + 1);
int brow = row % (this->buckets_per_group() + 1);
if (brow == 0) {
unsigned long width;
vis_line_t height;
tc.get_dimensions(height, width);
value_out.insert((unsigned int)0, width, '-');
this->hs_token_bucket = NULL;
}
else {
bucket_group_t bg = this->hs_group_keys[grow];
bucket_count_t total(0);
bucket_t::iterator iter;
int bucket_index;
bucket_index = brow - 1;
this->hs_token_bucket = &(this->hs_groups[bg][bucket_index]);
if (this->hs_label_source != NULL) {
this->hs_label_source->
hist_label_for_bucket((bg * this->hs_group_size) +
(bucket_index * this->hs_bucket_size),
*this->hs_token_bucket,
value_out);
}
}
}
void hist_source::text_attrs_for_line(textview_curses &tc,
int row,
string_attrs_t &value_out)
{
if (this->hs_token_bucket != NULL) {
view_colors &vc = view_colors::singleton();
unsigned long width, avail_width;
bucket_count_t total(0);
bucket_t::iterator iter;
vis_line_t height;
struct line_range lr;
tc.get_dimensions(height, width);
avail_width = width - this->hs_token_bucket->size();
lr.lr_start = 0;
for (iter = this->hs_token_bucket->begin();
iter != this->hs_token_bucket->end();
iter++) {
double percent = (double)(iter->second - this->hs_min_count) /
(this->hs_max_count - this->hs_min_count);
int amount, attrs;
attrs = vc.
reverse_attrs_for_role(this->get_role_for_type(iter->first));
amount = (int)rint(percent * avail_width);
if (iter->second == 0.0) {
amount = 0;
}
else {
amount = max(1, amount);
}
lr.lr_end = lr.lr_start + amount;
value_out[lr].insert(make_string_attr("style", attrs));
lr.lr_start = lr.lr_end;
}
}
}
void hist_source::add_value(int value, bucket_type_t bt, bucket_count_t amount)
{
bucket_group_t bg;
bg = bucket_group_t(value / this->hs_group_size);
bucket_array_t &ba = this->hs_groups[bg];
if (ba.empty()) {
ba.resize(this->buckets_per_group());
}
bucket_count_t &bc = ba[abs(value % this->hs_group_size) /
this->hs_bucket_size][bt];
bc += amount;
}
void hist_source::analyze(void)
{
std::map<bucket_group_t, bucket_array_t>::iterator iter;
this->hs_group_keys.clear();
this->hs_min_count = 3.40282347e+38F;
this->hs_max_count = 0.0;
for (iter = this->hs_groups.begin();
iter != this->hs_groups.end();
iter++) {
bucket_array_t::iterator ba_iter;
for (ba_iter = iter->second.begin();
ba_iter != iter->second.end();
ba_iter++) {
bucket_count_t total = 0.0;
bucket_t::iterator b_iter;
for (b_iter = ba_iter->begin();
b_iter != ba_iter->end();
b_iter++) {
if (b_iter->second != 0.0 &&
b_iter->second < this->hs_min_count) {
this->hs_min_count = b_iter->second;
}
total += b_iter->second;
}
if (total > this->hs_max_count) {
this->hs_max_count = total;
}
}
this->hs_group_keys.push_back(iter->first);
}
sort(this->hs_group_keys.begin(), this->hs_group_keys.end());
}

@ -0,0 +1,141 @@
#ifndef __hist_source_hh
#define __hist_source_hh
#include <map>
#include <string>
#include <vector>
#include "strong_int.hh"
#include "textview_curses.hh"
typedef float bucket_count_t;
STRONG_INT_TYPE(int, bucket_group);
STRONG_INT_TYPE(int, bucket_type);
class hist_source
: public text_sub_source {
public:
typedef std::map<bucket_type_t, bucket_count_t> bucket_t;
class label_source {
public:
virtual ~label_source() { };
virtual void hist_label_for_group(int group,
std::string &label_out) { };
virtual void hist_label_for_bucket(int bucket_start_value,
const bucket_t &bucket,
std::string &label_out) { };
};
hist_source();
virtual ~hist_source() { };
void set_bucket_size(int bs) { this->hs_bucket_size = bs; };
int get_bucket_size(void) const { return this->hs_bucket_size; };
void set_group_size(int gs) { this->hs_group_size = gs; };
int get_group_size(void) const { return this->hs_group_size; };
void set_label_source(label_source *hls)
{
this->hs_label_source = hls;
}
label_source *get_label_source(void)
{
return this->hs_label_source;
};
int buckets_per_group(void) const
{
return this->hs_group_size / this->hs_bucket_size;
};
void clear(void) { this->hs_groups.clear(); };
size_t text_line_count()
{
return (this->buckets_per_group() + 1) * this->hs_groups.size();
};
void set_role_for_type(bucket_type_t bt, view_colors::role_t role)
{
this->hs_type2role[bt] = role;
};
const view_colors::role_t &get_role_for_type(bucket_type_t bt)
{
return this->hs_type2role[bt];
};
void text_value_for_line(textview_curses &tc,
int row,
std::string &value_out,
bool no_scrub);
void text_attrs_for_line(textview_curses &tc,
int row,
string_attrs_t &value_out);
int value_for_row(vis_line_t row)
{
int grow = row / (this->buckets_per_group() + 1);
int brow = row % (this->buckets_per_group() + 1);
int retval = 0;
if (!this->hs_group_keys.empty()) {
bucket_group_t bg = this->hs_group_keys[grow];
if (brow > 0) {
brow -= 1;
}
retval = (bg * this->hs_group_size) + (brow * this->hs_bucket_size);
}
return retval;
};
vis_line_t row_for_value(int value)
{
vis_line_t retval;
if (!this->hs_group_keys.empty()) {
bucket_group_t bg(value / this->hs_group_size);
std::vector<bucket_group_t>::iterator lb;
lb = lower_bound(this->hs_group_keys.begin(),
this->hs_group_keys.end(),
bg);
retval = vis_line_t(distance(this->hs_group_keys.begin(), lb) *
(this->buckets_per_group() + 1));
retval += vis_line_t(1 +
(value % this->hs_group_size) /
this->hs_bucket_size);
}
return retval;
};
void add_value(int value, bucket_type_t bt, bucket_count_t amount = 1.0);
void analyze(void);
protected:
typedef std::vector<bucket_t> bucket_array_t;
std::map<bucket_type_t, view_colors::role_t> hs_type2role;
std::map<bucket_group_t, bucket_array_t> hs_groups;
std::vector<bucket_group_t> hs_group_keys;
int hs_bucket_size; /* hours */
int hs_group_size; /* days */
bucket_count_t hs_min_count;
bucket_count_t hs_max_count;
label_source *hs_label_source;
bucket_t *hs_token_bucket;
};
#endif

@ -0,0 +1,77 @@
#ifndef __hist_controller_hh
#define __hist_controller_hh
#include <map>
#include <string>
#include "strong_int.hh"
#include "listview_curses.hh"
STRONG_INT_TYPE(int, bucket_group);
STRONG_INT_TYPE(int, bucket_count);
class hist_data_source {
public:
virtual ~hist_data_source() { };
virtual int hist_values(void) = 0;
virtual void hist_value_for(int index, int &value_out) = 0;
};
class hist_label_source {
public:
virtual ~hist_label_source() { };
virtual void hist_label_for_group(int group, std::string &label_out) { };
};
class hist_controller : public list_data_source {
public:
hist_controller();
virtual ~hist_controller() { };
void set_bucket_size(int bs) { this->hv_bucket_size = bs; };
int get_bucket_size(void) const { return this->hv_bucket_size; };
void set_group_size(int gs) { this->hv_group_size = gs; };
int get_group_size(void) const { return this->hv_group_size; };
void set_data_source(hist_data_source *hds) {
this->hv_data_source = hds;
};
hist_data_source *get_data_source(void) { return this->hv_data_source; };
void set_label_source(hist_label_source *hls) {
this->hv_label_source = hls;
}
hist_label_source *get_label_source(void) {
return this->hv_label_source;
};
size_t listview_rows(void) {
return (this->hv_group_size / this->hv_bucket_size) *
this->hv_groups.size();
};
void listview_value_for_row(vis_line_t row, std::string &value_out);
void reload_data(void);
private:
typedef vector<bucket_count_t> buckets_t;
map<bucket_group_t, buckets_t> hv_groups;
int hv_bucket_size; // hours
int hv_group_size; // days
hist_data_source *hv_data_source;
hist_label_source *hv_label_source;
};
#endif

@ -0,0 +1,328 @@
/**
* @file line_buffer.cc
*/
#include "config.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <set>
#include "line_buffer.hh"
using namespace std;
static const size_t DEFAULT_LINE_BUFFER_SIZE = 256 * 1024;
static const size_t MAX_LINE_BUFFER_SIZE = 2 * DEFAULT_LINE_BUFFER_SIZE;
static const size_t DEFAULT_INCREMENT = 1024;
static set<line_buffer *> ALL_BUFFERS;
/*
* XXX REMOVE ME
*
* The stock gzipped file code does not use pread, so we need to use a lock to
* get exclusive access to the file. In the future, we should just rewrite
* the gzipped file code to use pread.
*/
class lock_hack {
public:
class guard {
public:
guard() : g_lock(lock_hack::singleton()) {
this->g_lock.lock();
};
~guard() {
this->g_lock.unlock();
};
private:
lock_hack &g_lock;
};
static lock_hack &singleton() {
static lock_hack retval;
return retval;
};
void lock() {
lockf(this->lh_fd, F_LOCK, 0);
};
void unlock() {
lockf(this->lh_fd, F_ULOCK, 0);
};
private:
lock_hack() {
char lockname[64];
snprintf(lockname, sizeof(lockname), "/tmp/lnav.%d.lck", getpid());
this->lh_fd = open(lockname, O_CREAT | O_RDWR, 0600);
unlink(lockname);
};
int lh_fd;
};
/* XXX END */
line_buffer::line_buffer()
: lb_gz_file(NULL),
lb_file_size((size_t) - 1),
lb_file_offset(0),
lb_buffer_size(0),
lb_buffer_max(DEFAULT_LINE_BUFFER_SIZE),
lb_seekable(false)
{
if ((this->lb_buffer = (char *)malloc(this->lb_buffer_max)) == NULL) {
throw bad_alloc();
}
ALL_BUFFERS.insert(this);
assert(this->invariant());
}
line_buffer::~line_buffer()
{
auto_fd fd = -1;
this->set_fd(fd);
ALL_BUFFERS.erase(this);
}
void line_buffer::set_fd(auto_fd &fd)
throw (error)
{
off_t newoff = 0;
if (this->lb_gz_file) {
gzclose(this->lb_gz_file);
this->lb_gz_file = NULL;
}
if (fd != -1) {
/* Sync the fd's offset with the object. */
newoff = lseek(fd, 0, SEEK_CUR);
if (newoff == -1) {
if (errno != ESPIPE) {
throw error(errno);
}
/* It's a pipe, start with a zero offset. */
newoff = 0;
this->lb_seekable = false;
}
else {
char gz_id[2];
if (pread(fd, gz_id, sizeof(gz_id), 0) == sizeof(gz_id)) {
if (gz_id[0] == '\037' && gz_id[1] == '\213') {
lseek(fd, 0, SEEK_SET);
if ((this->lb_gz_file = gzdopen(dup(fd), "r")) == NULL)
throw bad_alloc();
this->lb_gz_offset = lseek(this->lb_fd, 0, SEEK_CUR);
}
}
this->lb_seekable = true;
}
}
this->lb_file_offset = newoff;
this->lb_buffer_size = 0;
this->lb_fd = fd;
assert(this->invariant());
}
void line_buffer::ensure_available(off_t start, size_t max_length)
throw (error)
{
size_t prefill, available;
/* The file is probably bogus if a line has gotten this big. */
if (max_length > MAX_LINE_BUFFER_SIZE) {
throw error(EFBIG);
}
if (start < this->lb_file_offset ||
start > (off_t)(this->lb_file_offset + this->lb_buffer_size)) {
/*
* The request is outside the cached range, need to reload the
* whole thing.
*/
prefill = 0;
if (lseek(this->lb_fd, start, SEEK_SET) == -1) {
throw error(errno);
}
this->lb_file_offset = start;
this->lb_buffer_size = 0;
}
else {
/* The request is in the cached range. */
prefill = start - this->lb_file_offset;
}
assert(this->lb_file_offset <= start);
assert(prefill <= this->lb_buffer_size);
available = this->lb_buffer_max - this->lb_buffer_size;
assert(available <= this->lb_buffer_max);
if (max_length > available) {
/*
* Need more space, move any existing data to the front of the
* buffer.
*/
this->lb_buffer_size -= prefill;
this->lb_file_offset += prefill;
memmove(&this->lb_buffer[0],
&this->lb_buffer[prefill],
this->lb_buffer_size);
if (max_length > available) {
char *tmp, *old;
/* Still need more space, try a realloc. */
old = this->lb_buffer.release();
tmp = (char *)realloc(old,
this->lb_buffer_max +
DEFAULT_LINE_BUFFER_SIZE);
if (tmp != NULL) {
this->lb_buffer = tmp;
this->lb_buffer_max += DEFAULT_LINE_BUFFER_SIZE;
}
else {
this->lb_buffer = old;
throw error(ENOMEM);
}
}
}
}
bool line_buffer::fill_range(off_t start, size_t max_length)
throw (error)
{
bool retval = false;
if (this->in_range(start) && this->in_range(start + max_length)) {
/* Cache already has the data, nothing to do. */
retval = true;
}
else if (this->lb_fd != -1) {
int rc;
/* Make sure there is enough space, then */
this->ensure_available(start, max_length);
/* ... read in the new data. */
if (this->lb_gz_file) {
lock_hack::guard guard;
lseek(this->lb_fd, this->lb_gz_offset, SEEK_SET);
gzseek(this->lb_gz_file,
this->lb_file_offset + this->lb_buffer_size,
SEEK_SET);
rc = gzread(this->lb_gz_file,
&this->lb_buffer[this->lb_buffer_size],
this->lb_buffer_max - this->lb_buffer_size);
this->lb_gz_offset = lseek(this->lb_fd, 0, SEEK_CUR);
}
else if (this->lb_seekable) {
rc = pread(this->lb_fd,
&this->lb_buffer[this->lb_buffer_size],
this->lb_buffer_max - this->lb_buffer_size,
this->lb_file_offset + this->lb_buffer_size);
}
else {
rc = read(this->lb_fd,
&this->lb_buffer[this->lb_buffer_size],
this->lb_buffer_max - this->lb_buffer_size);
}
switch (rc) {
case 0:
this->lb_file_size = this->lb_file_offset + this->lb_buffer_size;
if (start < (off_t) this->lb_file_size) {
retval = true;
}
break;
case - 1:
switch (errno) {
case EINTR:
case EAGAIN:
break;
default:
throw error(errno);
}
break;
default:
this->lb_buffer_size += rc;
retval = true;
break;
}
assert(this->lb_buffer_size <= this->lb_buffer_max);
}
return retval;
}
char *line_buffer::read_line(off_t &offset, size_t &len_out, char delim)
throw (error)
{
size_t request_size = DEFAULT_INCREMENT;
char *retval = NULL;
int last_avail = 0;
assert(this->lb_fd != -1);
len_out = 0;
while ((retval == NULL) && this->fill_range(offset, request_size)) {
char *line_start, *lf;
/* Find the data in the cache and */
line_start = this->get_range(offset, len_out);
/* ... look for the end-of-line. */
if (((lf = (char *)memchr(line_start, delim, len_out)) != NULL) ||
((offset + len_out) == this->lb_file_size)) {
if (lf != NULL) {
len_out = lf - line_start;
offset += 1; /* Skip the delimiter. */
}
else {
/*
* Be nice and make sure there is room for the caller to
* add a NULL-terminator.
*/
this->ensure_available(offset, len_out + 1);
}
offset += len_out;
retval = line_start;
}
else {
request_size += DEFAULT_INCREMENT;
}
}
assert((retval == NULL) ||
(retval >= this->lb_buffer &&
retval < (this->lb_buffer + this->lb_buffer_size)));
assert(len_out <= this->lb_buffer_size);
assert(this->invariant());
return retval;
}

@ -0,0 +1,185 @@
/**
* @file line_buffer.hh
*/
#ifndef __line_buffer_hh
#define __line_buffer_hh
#include <errno.h>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>
#include <zlib.h>
#include <exception>
#include "auto_fd.hh"
#include "auto_mem.hh"
/**
* Buffer for reading whole lines out of file descriptors. The class presents
* a stateless interface, callers specify the offset where a line starts and
* the class takes care of caching the surrounding range and locating the
* delimiter.
*
* XXX A bit of a wheel reinvention, but I'm not sure how well the libraries
* handle non-blocking I/O...
*/
class line_buffer {
public:
class error
: public std::exception {
public:
error(int err)
: e_err(err) { };
int e_err;
};
/** Construct an empty line_buffer. */
line_buffer();
virtual ~line_buffer();
/** @param fd The file descriptor that data should be pulled from. */
void set_fd(auto_fd &fd) throw (error);
/** @return The file descriptor that data should be pulled from. */
int get_fd() { return this->lb_fd; };
void set_file_size(size_t fs) { this->lb_file_size = fs; };
/**
* @return The size of the file or the amount of data pulled from a pipe.
*/
size_t get_file_size() { return this->lb_file_size; };
/**
* Read up to the end of file or a given delimiter.
*
* @param offset_inout The offset in the file to start reading from. On
* return, it contains the offset where the next line should start or one
* past the size of the file.
* @param len_out On return, contains the length of the line, not including
* the delimiter.
* @param delim The character that splits lines in the input, defaults to a
* line feed.
* @return The address in the internal buffer where the line starts. The
* line is not terminated, but this method ensures there is room to NULL
* terminate the line. If any modifications are made to the line, such as
* NULL termination, the invalidate() must be called before re-reading the
* line to refresh the buffer.
*/
char *read_line(off_t &offset_inout, size_t &len_out, char delim = '\n')
throw (error);
/**
* Signal that the contents of the internal buffer have been modified and
* any attempts to re-read the currently cached line(s) should trigger
* another read from the file.
*/
void invalidate()
{
this->lb_file_offset += this->lb_buffer_size;
this->lb_buffer_size = 0;
};
/** Release any resources held by this object. */
void reset()
{
this->lb_fd.reset();
this->lb_file_offset = 0;
this->lb_file_size = (size_t)-1;
this->lb_buffer_size = 0;
};
/** Check the invariants for this object. */
bool invariant(void)
{
assert(this->lb_buffer != NULL);
assert(this->lb_buffer_size <= this->lb_buffer_max);
return true;
};
private:
/**
* @param off The file offset to check for in the buffer.
* @return True if the given offset is cached in the buffer.
*/
bool in_range(off_t off)
{
return this->lb_file_offset <= off &&
off < (int)(this->lb_file_offset + this->lb_buffer_size);
};
/**
* Ensure there is enough room in the buffer to cache a range of data from
* the file. First, this method will check to see if there is enough room
* from where 'start' begins in the buffer to the maximum buffer size. If
* this is not enough, the currently cached data at 'start' will be moved
* to the beginning of the buffer, overwriting any cached data earlier in
* the file. Finally, if this is still not enough, the buffer will be
* reallocated to make more room.
*
* @param start The file offset of the start of the line.
* @param max_length The amount of data to be cached in the buffer.
*/
void ensure_available(off_t start, size_t max_length) throw (error);
/**
* Fill the buffer with the given range of data from the file.
*
* @param start The file offset where data should start to be read from the
* file.
* @param max_length The maximum amount of data to read from the file.
* @return True if any data was read from the file.
*/
bool fill_range(off_t start, size_t max_length) throw (error);
/**
* After a successful fill, the cached data can be retrieved with this
* method.
*
* @param start The file offset to retrieve cached data for.
* @param avail_out On return, the amount of data currently cached at the
* given offset.
* @return A pointer to the start of the cached data in the internal
* buffer.
*/
char *get_range(off_t start, size_t &avail_out)
{
int buffer_offset = start - this->lb_file_offset;
char *retval;
assert(buffer_offset >= 0);
retval = &this->lb_buffer[buffer_offset];
avail_out = this->lb_buffer_size - buffer_offset;
return retval;
};
auto_fd lb_fd; /*< The file to read data from. */
gzFile lb_gz_file;
off_t lb_gz_offset;
auto_mem<char> lb_buffer; /*< The internal buffer where data is cached */
size_t lb_file_size; /*<
* The size of the file. When lb_fd refers to
* a pipe, this is set to the amount of data
* read from the pipe when EOF is reached.
*/
off_t lb_file_offset; /*<
* Data cached in the buffer comes from this
* offset in the file.
*/
size_t lb_buffer_size; /*< The amount of cached data in the buffer. */
size_t lb_buffer_max; /*< The size of the buffer memory. */
bool lb_seekable;
};
#endif

@ -0,0 +1,154 @@
/**
* @file listview_curses.cc
*/
#include "listview_curses.hh"
using namespace std;
listview_curses::listview_curses()
: lv_source(NULL),
lv_window(NULL),
lv_y(0),
lv_top(0),
lv_left(0),
lv_height(0),
lv_needs_update(true),
lv_show_scrollbar(true)
{ }
listview_curses::~listview_curses()
{ }
void listview_curses::reload_data(void)
{
if (this->lv_source == NULL) {
this->lv_top = vis_line_t(0);
}
else if (this->lv_top >= this->get_inner_height()) {
this->lv_top = max(vis_line_t(0),
vis_line_t(this->get_inner_height() - 1));
}
this->lv_needs_update = true;
}
bool listview_curses::handle_key(int ch)
{
vis_line_t height(0);
unsigned long width;
bool retval = true;
this->get_dimensions(height, width);
switch (ch) {
case 'l':
case KEY_RIGHT:
this->shift_left(width / 2);
break;
case 'h':
case KEY_LEFT:
this->shift_left(-(width / 2));
break;
case '\r':
case 'j':
case KEY_DOWN:
this->shift_top(vis_line_t(1));
break;
case 'k':
case KEY_UP:
this->shift_top(vis_line_t(-1));
break;
case 'b':
case KEY_BACKSPACE:
case KEY_PPAGE:
this->shift_top(-height);
break;
case ' ':
case KEY_NPAGE:
this->shift_top(height);
break;
case KEY_HOME:
this->set_top(vis_line_t(0));
break;
case KEY_END:
case 'B':
this->set_top(max(vis_line_t(0),
max(this->lv_top,
vis_line_t(this->get_inner_height() - height + 1))));
break;
default:
retval = false;
break;
}
return retval;
}
void listview_curses::do_update(void)
{
if (this->lv_window != NULL && this->lv_needs_update) {
vis_line_t y(this->lv_y), height, bottom, lines;
struct line_range lr;
unsigned long width;
size_t row_count;
this->get_dimensions(height, width);
lr.lr_start = this->lv_left;
lr.lr_end = this->lv_left + width;
row_count = this->get_inner_height();
if (this->lv_top >= (int)row_count) {
this->lv_top = max(vis_line_t(0), vis_line_t(row_count) - height);
}
lines = y + min(height, vis_line_t(row_count) - this->lv_top);
bottom = y + height;
for (; y < lines; ++y) {
vis_line_t row = this->lv_top + y - vis_line_t(this->lv_y);
attr_line_t al;
string line;
this->lv_source->listview_value_for_row(*this, row, al);
this->mvwattrline(this->lv_window, y, 0, al, lr);
}
/* Clear out any remaining lines on the display. */
for (; y < bottom; ++y) {
wmove(this->lv_window, y, 0);
wclrtoeol(this->lv_window);
}
if (this->lv_show_scrollbar) {
double progress = 1.0;
double coverage = 1.0;
if (this->get_inner_height() > 0) {
progress = (double)this->lv_top / (double)this->get_inner_height();
coverage = (double)height / (double)this->get_inner_height();
}
y = vis_line_t(this->lv_y) +
vis_line_t((int)(progress * (double)height));
lines = y + min(height, vis_line_t((int)(coverage * (double)height)));
for (; y <= lines; ++y) {
char buffer;
mvwinnstr(this->lv_window, y, width - 1, &buffer, 1);
wattron(this->lv_window, A_REVERSE);
mvwaddnstr(this->lv_window, y, width - 1, &buffer, 1);
wattroff(this->lv_window, A_REVERSE);
}
wmove(this->lv_window, this->lv_y + height - 1, 0);
}
this->lv_needs_update = false;
}
}

@ -0,0 +1,256 @@
/**
* @file listview_curses.hh
*/
#ifndef __listview_curses_hh
#define __listview_curses_hh
#include <curses.h>
#include <sys/types.h>
#include <string>
#include <algorithm>
#include "strong_int.hh"
#include "view_curses.hh"
/** Strongly-typed for lines to be displayed. */
STRONG_INT_TYPE(int, vis_line);
class listview_curses;
/**
* Data source for lines to be displayed by the listview_curses object.
*/
class list_data_source {
public:
virtual ~list_data_source() { };
/** @return The number of rows in the list. */
virtual size_t listview_rows(const listview_curses &lv) = 0;
/**
* Get the string value for a row in the list.
*
* @param row The row number.
* @param value_out The destination for the string value.
*/
virtual void listview_value_for_row(const listview_curses &lv,
vis_line_t row,
attr_line_t &value_out) = 0;
};
/**
* View that displays a list of lines that can optionally contain highlighting.
*/
class listview_curses
: public view_curses {
public:
typedef view_action<listview_curses> action;
/** Construct an empty list view. */
listview_curses();
virtual ~listview_curses();
/** @param src The data source delegate. */
void set_data_source(list_data_source *src)
{
this->lv_source = src;
if (this->lv_source != NULL) {
this->reload_data();
}
};
/** @return The data source delegate. */
list_data_source *get_data_source() { return this->lv_source; };
/**
* @param va The action to invoke when the view is scrolled.
* @todo Allow multiple observers.
*/
void set_scroll_action(action va) { this->lv_scroll = va; };
template<class _Receiver>
void set_scroll_action(action::mem_functor_t < _Receiver > *mf)
{
this->lv_scroll = action(mf);
};
void set_show_scrollbar(bool ss) { this->lv_show_scrollbar = ss; };
bool get_show_scrollbar() { return this->lv_show_scrollbar; };
/** @param win The curses window this view is attached to. */
void set_window(WINDOW *win) { this->lv_window = win; };
/** @return The curses window this view is attached to. */
WINDOW *get_window() { return this->lv_window; };
void set_y(int y)
{
if (y != this->lv_y) {
this->lv_y = y;
this->lv_needs_update = true;
}
};
int get_y() { return this->lv_y; };
/**
* Set the line number to be displayed at the top of the view. If the
* value is invalid, flash() will be called. If the value is valid, the
* new value will be set and the scroll action called.
*
* @param top The new value for top.
*/
void set_top(vis_line_t top)
{
if (top < 0 || (top > 0 && top >= this->get_inner_height())) {
flash();
}
else if (this->lv_top != top) {
this->lv_top = top;
this->lv_scroll.invoke(this);
this->lv_needs_update = true;
}
};
/** @return The line number that is displayed at the top. */
vis_line_t get_top() { return this->lv_top; };
vis_line_t get_bottom()
{
vis_line_t retval, height;
unsigned long width;
this->get_dimensions(height, width);
retval = std::min(this->lv_top + height - vis_line_t(1),
vis_line_t(this->get_inner_height() - 1));
return retval;
};
/**
* Shift the value of top by the given value.
*
* @param offset The amount to change top by.
* @return The final value of top.
*/
vis_line_t shift_top(vis_line_t offset)
{
if (offset < 0 && this->lv_top == 0) {
flash();
}
else {
this->set_top(std::max(vis_line_t(0), this->lv_top + offset));
}
return this->lv_top;
};
/**
* Set the column number to be displayed at the left of the view. If the
* value is invalid, flash() will be called. If the value is valid, the
* new value will be set and the scroll action called.
*
* @param left The new value for left.
*/
void set_left(int left)
{
if (left >= 0 && this->lv_left != left) {
this->lv_left = left;
this->lv_scroll.invoke(this);
this->lv_needs_update = true;
}
};
/** @return The column number that is displayed at the left. */
int get_left() { return this->lv_left; };
/**
* Shift the value of left by the given value.
*
* @param offset The amount to change top by.
* @return The final value of top.
*/
int shift_left(int offset)
{
this->set_left(std::max(0, this->lv_left + offset));
return this->lv_left;
};
/**
* Set the height of the view. A value greater than one is considered to
* be an absolute size. A value less than or equal to zero makes the
* height relative to the size of the enclosing window.
*
* @height The new height.
*/
void set_height(vis_line_t height)
{
if (this->lv_height != height) {
this->lv_height = height;
this->lv_needs_update = true;
}
};
/** @return The absolute or relative height of the window. */
vis_line_t get_height() { return this->lv_height; };
int get_inner_height() const
{
return this->lv_source == NULL ? 0 :
this->lv_source->listview_rows(*this);
};
void set_needs_update() { this->lv_needs_update = true; };
/**
* Get the actual dimensions of the view.
*
* @param height_out The actual height of the view in lines.
* @param width_out The actual width of the view in columns.
*/
void get_dimensions(vis_line_t &height_out, unsigned long &width_out)
{
unsigned long height;
getmaxyx(this->lv_window, height, width_out);
if (this->lv_height < 1) {
height_out = vis_line_t(height) +
this->lv_height -
vis_line_t(this->lv_y);
}
else {
height_out = this->lv_height;
}
};
/** This method should be called when the data source has changed. */
void reload_data(void);
/**
* @param ch The input to be handled.
* @return True if the key was eaten by this view.
*/
bool handle_key(int ch);
/**
* Query the data source and draw the visible lines on the display.
*/
void do_update(void);
protected:
list_data_source *lv_source; /*< The data source delegate. */
action lv_scroll; /*< The scroll action. */
WINDOW *lv_window; /*< The window that contains this view. */
int lv_y;
vis_line_t lv_top; /*< The line at the top of the view. */
int lv_left; /*< The column at the left of the view. */
vis_line_t lv_height; /*< The abs/rel height of the view. */
bool lv_needs_update;
bool lv_show_scrollbar;
};
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,55 @@
/**
* @file lnav_util.hh
*
* Dumping ground for useful functions with no other home.
*/
#ifndef __lnav_util_hh
#define __lnav_util_hh
#include <sys/types.h>
/**
* Round down a number based on a given granularity.
*
* @param
* @param step The granularity.
*/
inline int rounddown(size_t size, int step)
{
return (size - (size % step));
}
inline int rounddown_offset(size_t size, int step, int offset)
{
return (size - ((size - offset) % step));
}
inline int roundup(size_t size, int step)
{
int retval = size + step;
retval -= (retval % step);
return retval;
}
inline time_t day_num(time_t ti)
{
return ti / (24 * 60 * 60);
}
inline time_t hour_num(time_t ti)
{
return ti / (60 * 60);
}
#if SIZEOF_OFF_T == 8
#define FORMAT_OFF_T "%qd"
#elif SIZEOF_OFF_T == 4
#define FORMAT_OFF_T "%ld"
#else
#error "off_t has unhandled size..."
#endif
#endif

@ -0,0 +1,201 @@
#include "tables.h"
#include "log_format.hh"
using namespace std;
/*
* Supported formats:
* generic
* syslog
* apache
* tcpdump
* strace
* vstrace
* csv (?)
* file system (?)
* plugins
* vmstat
* iostat
*/
static time_t BAD_DATE = -1;
static time_t tm2sec(const struct tm *t)
{
int year;
time_t days;
const int dayoffset[12] =
{ 306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275 };
year = t->tm_year;
if (year < 70 || ((sizeof(time_t) <= 4) && (year >= 138))) {
return BAD_DATE;
}
/* shift new year to 1st March in order to make leap year calc easy */
if (t->tm_mon < 2) {
year--;
}
/* Find number of days since 1st March 1900 (in the Gregorian calendar). */
days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4;
days += dayoffset[t->tm_mon] + t->tm_mday - 1;
days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */
days = ((days * 24 + t->tm_hour) * 60 + t->tm_min) * 60 + t->tm_sec;
if (days < 0) {
return BAD_DATE;
} /* must have overflowed */
else {
return days;
} /* must be a valid time */
}
const char *logline::level_names[LEVEL__MAX] = {
"unknown",
"trace",
"debug",
"info",
"warning",
"error",
"critical"
};
logline::level_t logline::string2level(const char *levelstr)
{
logline::level_t retval = logline::LEVEL_UNKNOWN;
if (strcasestr(levelstr, "TRACE")) {
retval = logline::LEVEL_TRACE;
}
else if (strcasestr(levelstr, "VERBOSE")) {
retval = logline::LEVEL_DEBUG;
}
else if (strcasestr(levelstr, "DEBUG")) {
retval = logline::LEVEL_DEBUG;
}
else if (strcasestr(levelstr, "INFO")) {
retval = logline::LEVEL_INFO;
}
else if (strcasestr(levelstr, "WARNING")) {
retval = logline::LEVEL_WARNING;
}
else if (strcasestr(levelstr, "ERROR")) {
retval = logline::LEVEL_ERROR;
}
else if (strcasestr(levelstr, "CRITICAL")) {
retval = logline::LEVEL_CRITICAL;
}
return retval;
}
vector<log_format *> log_format::lf_root_formats;
vector<log_format *> &log_format::get_root_formats(void)
{
return lf_root_formats;
}
static bool next_format(const char *fmt[], int &index, int &locked_index)
{
bool retval = true;
if (locked_index == -1) {
index += 1;
if (fmt[index] == NULL)
retval = false;
}
else if (index == locked_index) {
retval = false;
}
else {
index = locked_index;
}
return retval;
}
int log_format::log_scanf(const char *line,
const char *fmt[],
int expected_matches,
const char *time_fmt[],
char *time_dest,
struct tm *tm_out,
time_t &time_out,
...)
{
static const char *std_time_fmt[] = {
"%Y-%m-%d %H:%M:%S",
"%Y-%m-%d %H:%M",
"%Y/%m/%d %H:%M:%S",
"%Y/%m/%d %H:%M",
"%d/%b/%Y:%H:%M:%S %z",
"%b %d %H:%M:%S",
NULL,
};
int curr_fmt = -1, retval = 0;
va_list args;
va_start(args, time_out);
while (next_format(fmt, curr_fmt, this->lf_fmt_lock)) {
time_dest[0] = '\0';
memset(tm_out, 0, sizeof(struct tm));
retval = vsscanf(line, fmt[curr_fmt], args);
if (retval < expected_matches) {
retval = 0;
continue;
}
if (time_dest[0] == '\0') {
retval = 0;
}
else {
int curr_time_fmt = -1;
bool found = false;
if (!time_fmt)
time_fmt = std_time_fmt;
while (next_format(time_fmt,
curr_time_fmt,
this->lf_time_fmt_lock)) {
if (strptime(time_dest,
time_fmt[curr_time_fmt],
tm_out) != NULL) {
if (tm_out->tm_year < 70) {
tm_out->tm_year = 1970;
}
time_out = tm2sec(tm_out);
this->lf_fmt_lock = curr_fmt;
this->lf_time_fmt_lock = curr_time_fmt;
found = true;
break;
}
}
if (!found)
retval = 0;
}
}
va_end(args);
return retval;
}
// XXX
#include "log_format_impls.cc"

@ -0,0 +1,151 @@
#ifndef __log_format_hh
#define __log_format_hh
#include <assert.h>
#include <time.h>
#include <sys/types.h>
#include <string>
#include <vector>
/**
* Metadata for a single line in a log file.
*/
class logline {
public:
/**
* The logging level identifiers for a line(s).
*/
typedef enum {
LEVEL_UNKNOWN,
LEVEL_TRACE,
LEVEL_DEBUG,
LEVEL_INFO,
LEVEL_WARNING,
LEVEL_ERROR,
LEVEL_CRITICAL,
LEVEL__MAX,
LEVEL_MULTILINE = 0x40, /*< Start of a multiline entry. (Unused) */
LEVEL_CONTINUED = 0x80, /*< Continuation of multiline entry. */
/** Mask of flags for the level field. */
LEVEL__FLAGS = (LEVEL_MULTILINE | LEVEL_CONTINUED)
} level_t;
static const char *level_names[LEVEL__MAX];
static level_t string2level(const char *levelstr);
/**
* Construct a logline object with the given values.
*
* @param off The offset of the line in the file.
* @param t The timestamp for the line.
* @param millis The millisecond timestamp for the line.
* @param l The logging level.
*/
logline(off_t off,
time_t t,
uint16_t millis,
level_t l,
uint8_t m = 0)
: ll_offset(off),
ll_time(t),
ll_millis(millis),
ll_level(l),
ll_module(m) { };
/** @return The offset of the line in the file. */
off_t get_offset() const { return this->ll_offset; };
/** @return The timestamp for the line. */
time_t get_time() const { return this->ll_time; };
void set_time(time_t t) { this->ll_time = t; };
/** @return The millisecond timestamp for the line. */
uint16_t get_millis() const { return this->ll_millis; };
void set_multiline(void) { this->ll_level |= LEVEL_MULTILINE; };
/** @param l The logging level. */
void set_level(level_t l) { this->ll_level = l; };
/** @return The logging level. */
level_t get_level() const { return (level_t)(this->ll_level & 0xff); };
const char *get_level_name() const {
return level_names[this->ll_level & 0x0f];
};
uint8_t get_module() const { return this->ll_module; };
/**
* Compare loglines based on their timestamp.
*/
bool operator<(const logline &rhs) const
{
return this->ll_time < rhs.ll_time ||
(this->ll_time == rhs.ll_time &&
this->ll_millis < rhs.ll_millis);
};
bool operator<(const time_t &rhs) { return this->ll_time < rhs; };
private:
off_t ll_offset;
time_t ll_time;
uint16_t ll_millis;
uint8_t ll_level;
uint8_t ll_module;
};
class log_format {
public:
static std::vector<log_format *> &get_root_formats(void);
template<class T> class register_root_format {
public:
register_root_format() {
log_format::lf_root_formats.push_back(new T());
};
};
log_format() : lf_fmt_lock(-1), lf_time_fmt_lock(-1) { };
virtual ~log_format() { };
virtual void clear(void) {
this->lf_fmt_lock = -1;
this->lf_time_fmt_lock = -1;
};
virtual std::string get_name(void) = 0;
virtual bool scan(std::vector< logline > &dst,
off_t offset,
char *prefix,
int len) = 0;
virtual std::auto_ptr<log_format> specialized(void) = 0;
protected:
static std::vector<log_format *> lf_root_formats;
int log_scanf(const char *line,
const char *fmt[],
int expected_matches,
const char *time_fmt[],
char *time_dest,
struct tm *tm_out,
time_t &time_out,
...);
int lf_fmt_lock;
int lf_time_fmt_lock;
};
#endif

@ -0,0 +1,285 @@
#include <soci.h>
#include "tables.h"
#include "log_format.hh"
#include "log_vtab_impl.hh"
using namespace std;
using namespace soci;
class access_log_format : public log_format {
string get_name() { return "access_log"; };
bool scan(vector < logline > &dst,
off_t offset,
char *prefix,
int len) {
static const char *log_fmt[] = {
"%*s %*s %*s [%63[^]]] \"%*[^\"]\" %d",
NULL
};
bool retval = false;
struct tm log_time;
int http_code = 0;
char timestr[64];
time_t line_time;
if (this->log_scanf(prefix,
log_fmt,
2,
NULL,
timestr,
&log_time,
line_time,
timestr,
&http_code)) {
logline::level_t ll = logline::LEVEL_UNKNOWN;
if (http_code < 400) {
ll = logline::LEVEL_INFO;
}
else {
ll = logline::LEVEL_ERROR;
}
dst.push_back(logline(offset,
line_time,
0,
ll));
retval = true;
}
return retval;
};
auto_ptr<log_format> specialized() {
auto_ptr<log_format> retval((log_format *)new access_log_format(*this));
return retval;
};
};
log_format::register_root_format<access_log_format> access_log_instance;
class syslog_log_format : public log_format {
string get_name() { return "syslog_log"; };
bool scan(vector < logline > &dst,
off_t offset,
char *prefix,
int len) {
bool retval = false;
struct tm log_time;
short millis = 0;
time_t now;
char *rest;
now = time(NULL);
log_time = *localtime(&now);
log_time.tm_isdst = 0;
if ((rest = strptime(prefix,
"%b %d %H:%M:%S",
&log_time)) != NULL) {
logline::level_t ll = logline::LEVEL_UNKNOWN;
time_t log_gmt;
if (strcasestr(prefix, "failed") != NULL ||
strcasestr(prefix, "failure") != NULL ||
strcasestr(prefix, "error") != NULL) {
ll = logline::LEVEL_ERROR;
}
else if (strcasestr(prefix, "warn") != NULL ||
strcasestr(prefix, "not responding") != NULL ||
strcasestr(prefix, "init: cannot execute") != NULL) {
ll = logline::LEVEL_WARNING;
}
log_gmt = tm2sec(&log_time);
if (!dst.empty() &&
((dst.back().get_time() - log_gmt) > (24 * 60 * 60))) {
vector<logline>::iterator iter;
for (iter = dst.begin(); iter != dst.end(); iter++) {
time_t ot = iter->get_time();
struct tm *otm;
otm = gmtime(&ot);
otm->tm_year -= 1;
iter->set_time(tm2sec(otm));
}
}
dst.push_back(logline(offset, log_gmt, millis, ll));
retval = true;
}
return retval;
};
auto_ptr<log_format> specialized() {
auto_ptr<log_format> retval((log_format *)new syslog_log_format(*this));
return retval;
};
};
log_format::register_root_format<syslog_log_format> syslog_instance;
class tcsh_history_format : public log_format {
string get_name() { return "tcsh_history"; };
bool scan(vector < logline > &dst,
off_t offset,
char *prefix,
int len) {
bool retval = false;
time_t log_time;
if (sscanf(prefix, "#+%d", &log_time) == 1) {
struct tm log_tm;
memset(&log_tm, 0, sizeof(log_tm));
log_tm = *localtime( &log_time);
log_tm.tm_isdst = 0;
dst.push_back(logline(offset,
mktime(&log_tm) - timezone,
0,
logline::LEVEL_UNKNOWN));
retval = true;
}
return retval;
};
auto_ptr<log_format> specialized() {
auto_ptr<log_format> retval((log_format *)
new tcsh_history_format(*this));
return retval;
};
};
log_format::register_root_format<tcsh_history_format> tcsh_instance;
class generic_log_format : public log_format {
string get_name() { return "generic_log"; };
bool scan(vector < logline > &dst,
off_t offset,
char *prefix,
int len) {
static const char *log_fmt[] = {
"%63[0-9: ,-] %15s",
"[%63[0-9: -]] %15s",
"[%63[0-9: .-] %*s %15s",
"[%63[0-9: -]] (%*d) %15s",
NULL
};
bool retval = false;
struct tm log_time;
char timestr[64];
time_t line_time;
char level[16];
if (this->log_scanf(prefix,
log_fmt,
2,
NULL,
timestr,
&log_time,
line_time,
timestr,
level)) {
dst.push_back(logline(offset,
line_time,
0,
logline::string2level(level)));
retval = true;
}
return retval;
};
auto_ptr<log_format> specialized() {
auto_ptr<log_format> retval((log_format *)
new generic_log_format(*this));
return retval;
};
};
log_format::register_root_format<generic_log_format> generic_log_instance;
class strace_log_format : public log_format {
string get_name() { return "strace_log"; };
bool scan(vector < logline > &dst,
off_t offset,
char *prefix,
int len) {
static const char *log_fmt[] = {
"%63[0-9:].%d",
NULL
};
static const char *time_fmt[] = {
"%H:%M:%S",
NULL
};
bool retval = false;
struct tm log_time;
char timestr[64];
time_t line_time;
int usecs;
if (this->log_scanf(prefix,
log_fmt,
2,
time_fmt,
timestr,
&log_time,
line_time,
timestr,
&usecs)) {
logline::level_t level = logline::LEVEL_UNKNOWN;
const char *eq;
if ((eq = strrchr(prefix, '=')) != NULL) {
int rc;
if (sscanf(eq, "= %d", &rc) == 1 && rc < 0) {
level = logline::LEVEL_ERROR;
}
}
if (!dst.empty() && (line_time < dst.back().get_time())) {
line_time += (24 * 60 * 60);
}
dst.push_back(logline(offset,
line_time,
usecs / 1000,
level));
retval = true;
}
return retval;
};
auto_ptr<log_format> specialized() {
auto_ptr<log_format> retval((log_format *)
new strace_log_format(*this));
return retval;
};
};
log_format::register_root_format<strace_log_format> strace_log_instance;

@ -0,0 +1,307 @@
#include "config.h"
#include "log_vtab_impl.hh"
#include "logfile_sub_source.hh"
using namespace std;
using namespace soci;
using namespace sqlite_api;
static string declare_table_statement(log_vtab_impl *vi)
{
std::vector<log_vtab_impl::vtab_column> cols;
std::vector<log_vtab_impl::vtab_column>::const_iterator iter;
std::ostringstream oss;
oss << "CREATE TABLE unused (\n"
<< " line_number int,\n"
<< " path text,\n"
<< " log_time datetime,\n"
<< " level text,\n"
<< " raw_line text";
vi->get_columns(cols);
for (iter = cols.begin(); iter != cols.end(); iter++) {
oss << ",\n";
oss << " " << iter->vc_name << " " << iter->vc_type;
}
oss << "\n);";
return oss.str();
}
struct vtab {
sqlite3_vtab base;
sqlite_api::sqlite3 *db;
logfile_sub_source *lss;
log_vtab_impl *vi;
};
struct vtab_cursor {
sqlite3_vtab_cursor base;
vis_line_t curr_line;
};
static int vt_destructor(sqlite3_vtab *p_svt);
static int vt_create( sqlite_api::sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **pp_vt,
char **pzErr )
{
log_vtab_manager *vm = (log_vtab_manager *)pAux;
int rc = SQLITE_OK;
log_vtab_impl *vi;
vtab* p_vt;
/* Allocate the sqlite3_vtab/vtab structure itself */
p_vt = (vtab*)sqlite3_malloc(sizeof(*p_vt));
if(p_vt == NULL)
{
return SQLITE_NOMEM;
}
p_vt->db = db;
/* Declare the vtable's structure */
p_vt->vi = vm->lookup_impl(argv[3]);
p_vt->lss = vm->get_source();
rc = sqlite3_declare_vtab(db, declare_table_statement(p_vt->vi).c_str());
/* Success. Set *pp_vt and return */
*pp_vt = &p_vt->base;
return SQLITE_OK;
}
static int vt_destructor(sqlite3_vtab *p_svt)
{
vtab *p_vt = (vtab*)p_svt;
/* Free the SQLite structure */
sqlite3_free(p_vt);
return SQLITE_OK;
}
static int vt_connect( sqlite_api::sqlite3 *db, void *p_aux,
int argc, const char *const*argv,
sqlite3_vtab **pp_vt, char **pzErr )
{
return vt_create(db, p_aux, argc, argv, pp_vt, pzErr);
}
static int vt_disconnect(sqlite3_vtab *pVtab)
{
return vt_destructor(pVtab);
}
static int vt_destroy(sqlite3_vtab *p_vt)
{
return vt_destructor(p_vt);
}
static int vt_next(sqlite3_vtab_cursor *cur);
static int vt_open(sqlite3_vtab *p_svt, sqlite3_vtab_cursor **pp_cursor)
{
vtab* p_vt = (vtab*)p_svt;
p_vt->base.zErrMsg = NULL;
vtab_cursor *p_cur =
(vtab_cursor*)sqlite3_malloc(sizeof(vtab_cursor));
*pp_cursor = (sqlite3_vtab_cursor*)p_cur;
p_cur->base.pVtab = p_svt;
p_cur->curr_line = vis_line_t(-1);
vt_next((sqlite3_vtab_cursor *)p_cur);
return (p_cur ? SQLITE_OK : SQLITE_NOMEM);
}
static int vt_close(sqlite3_vtab_cursor *cur)
{
vtab_cursor *p_cur = (vtab_cursor*)cur;
/* Free cursor struct. */
sqlite3_free(p_cur);
return SQLITE_OK;
}
static int vt_eof(sqlite3_vtab_cursor *cur)
{
vtab_cursor *vc = (vtab_cursor *)cur;
vtab *vt = (vtab *)cur->pVtab;
return vc->curr_line == vt->lss->text_line_count();
}
static int vt_next(sqlite3_vtab_cursor *cur)
{
vtab_cursor *vc = (vtab_cursor *)cur;
vtab *vt = (vtab *)cur->pVtab;
const string &format_name = vt->vi->get_name();
bool done = false;
do {
vc->curr_line = vc->curr_line + vis_line_t(1);
if (vc->curr_line == vt->lss->text_line_count())
break;
content_line_t cl(vt->lss->at(vc->curr_line));
logfile *lf = vt->lss->find(cl);
log_format *format = lf->get_format();
if (format != NULL && format->get_name() == format_name) {
done = true;
}
}
while (!done);
return SQLITE_OK;
}
static int vt_column(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col)
{
vtab_cursor *vc = (vtab_cursor *)cur;
vtab *vt = (vtab *)cur->pVtab;
content_line_t cl(vt->lss->at(vc->curr_line));
logfile *lf = vt->lss->find(cl);
logfile::iterator ll = lf->begin() + cl;
/* Just return the ordinal of the column requested. */
switch(col)
{
case 0:
{
sqlite3_result_int64( ctx, vc->curr_line );
}
break;
case 1:
{
string &fn = lf->get_filename();
sqlite3_result_text( ctx,
fn.c_str(),
fn.length(),
SQLITE_STATIC );
}
break;
case 2:
{
time_t line_time;
char buffer[64];
line_time = ll->get_time();
strftime(buffer, sizeof(buffer),
"%F %T",
gmtime(&line_time));
sqlite3_result_text(ctx, buffer, strlen(buffer), SQLITE_TRANSIENT);
}
break;
case 3:
{
const char *level_name = ll->get_level_name();
sqlite3_result_text(ctx,
level_name,
strlen(level_name),
SQLITE_STATIC);
}
break;
case 4:
{
string line;
lf->read_line(ll, line);
sqlite3_result_text(ctx,
line.c_str(),
line.length(),
SQLITE_TRANSIENT);
}
break;
default:
{
logfile::iterator line_iter;
string line, value;
line_iter = lf->begin() + cl;
lf->read_line(line_iter, line);
vt->vi->extract(line, col - 5, ctx);
}
break;
}
return SQLITE_OK;
}
static int vt_rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *p_rowid)
{
vtab_cursor *p_cur = (vtab_cursor*)cur;
*p_rowid = p_cur->curr_line;
return SQLITE_OK;
}
static int vt_filter( sqlite3_vtab_cursor *p_vtc,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv )
{
return SQLITE_OK;
}
static int vt_best_index(sqlite3_vtab *tab, sqlite3_index_info *p_info)
{
return SQLITE_OK;
}
static sqlite_api::sqlite3_module vtab_module = {
0, /* iVersion */
vt_create, /* xCreate - create a vtable */
vt_connect, /* xConnect - associate a vtable with a connection */
vt_best_index, /* xBestIndex - best index */
vt_disconnect, /* xDisconnect - disassociate a vtable with a connection */
vt_destroy, /* xDestroy - destroy a vtable */
vt_open, /* xOpen - open a cursor */
vt_close, /* xClose - close a cursor */
vt_filter, /* xFilter - configure scan constraints */
vt_next, /* xNext - advance a cursor */
vt_eof, /* xEof - inidicate end of result set*/
vt_column, /* xColumn - read data */
vt_rowid, /* xRowid - read data */
NULL, /* xUpdate - write data */
NULL, /* xBegin - begin transaction */
NULL, /* xSync - sync transaction */
NULL, /* xCommit - commit transaction */
NULL, /* xRollback - rollback transaction */
NULL, /* xFindFunction - function overloading */
};
log_vtab_manager::log_vtab_manager(soci::session &sql, logfile_sub_source &lss)
: vm_sql(sql), vm_source(lss)
{
sqlite3_session_backend *be = (sqlite3_session_backend *)sql.get_backend();
sqlite_api::sqlite3 *db = be->conn_;
sqlite3_create_module(db, "log_vtab_impl", &vtab_module, this);
}
void log_vtab_manager::register_vtab(log_vtab_impl *vi) {
if (this->vm_impls.find(vi->get_name()) == this->vm_impls.end()) {
this->vm_impls[vi->get_name()] = vi;
vm_sql << "CREATE VIRTUAL TABLE "
<< vi->get_name()
<< " USING log_vtab_impl("
<< vi->get_name()
<< ")";
}
}

@ -0,0 +1,60 @@
#ifndef __vtab_impl_hh
#define __vtab_impl_hh
#include <soci.h>
#include <sqlite3/soci-sqlite3.h>
#include <sqlite3.h>
#include <map>
#include <string>
class logfile_sub_source;
class log_vtab_impl {
public:
struct vtab_column {
vtab_column(const char *name, const char *type)
: vc_name(name), vc_type(type) { };
const char *vc_name;
const char *vc_type;
};
log_vtab_impl(const std::string name) : vi_name(name) { };
virtual ~log_vtab_impl() { };
const std::string &get_name(void) const {
return this->vi_name;
};
virtual void get_columns(std::vector<vtab_column> &cols) { };
virtual void extract(const std::string &line,
int column,
sqlite_api::sqlite3_context *ctx) {
};
private:
const std::string vi_name;
};
class log_vtab_manager {
public:
log_vtab_manager(soci::session &sql, logfile_sub_source &lss);
logfile_sub_source *get_source() { return &this->vm_source; };
void register_vtab(log_vtab_impl *vi);
log_vtab_impl *lookup_impl(std::string name) {
return this->vm_impls[name];
};
private:
soci::session &vm_sql;
logfile_sub_source &vm_source;
std::map<std::string, log_vtab_impl *> vm_impls;
};
#endif

@ -0,0 +1,207 @@
/**
* @file logfile.cc
*/
#include "config.h"
#include <stdio.h>
#define __USE_GNU
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <time.h>
#include "logfile.hh"
using namespace std;
logfile::logfile(string filename, auto_fd fd)
throw (error)
: lf_filename(filename),
lf_index_time(0),
lf_index_size(0)
{
int reserve_size = 100;
assert(filename.size() > 0);
if (fd == -1) {
char resolved_path[PATH_MAX];
struct stat st;
errno = 0;
if (realpath(filename.c_str(), resolved_path) == NULL) {
throw error(resolved_path, errno);
}
filename = resolved_path;
if (stat(filename.c_str(), &st) == -1) {
throw error(filename, errno);
}
reserve_size = st.st_size / 100;
if (!S_ISREG(st.st_mode)) {
throw error(filename, EINVAL);
}
if ((fd = open(filename.c_str(), O_RDONLY)) == -1) {
throw error(filename, errno);
}
}
this->lf_line_buffer.set_fd(fd);
this->lf_index.reserve(reserve_size);
assert(this->invariant());
}
logfile::~logfile()
{ }
void logfile::process_prefix(off_t offset, char *prefix, int len)
{
bool found = false;
int lpc;
if (this->lf_format.get() != NULL) {
/* We've locked onto a format, just use that scanner. */
found = this->lf_format->scan(this->lf_index, offset, prefix, len);
}
else {
vector<log_format *> &root_formats = log_format::get_root_formats();
vector<log_format *>::iterator iter;
/*
* Try each scanner until we get a match. Fortunately, all the formats
* are sufficiently different that there are no ambiguities...
*/
for (iter = root_formats.begin();
iter != root_formats.end() && !found;
iter++) {
(*iter)->clear();
if ((*iter)->scan(this->lf_index, offset, prefix, len)) {
#if 0
assert(this->lf_index.size() == 1 ||
(this->lf_index[this->lf_index.size() - 2] <
this->lf_index[this->lf_index.size() - 1]));
#endif
this->lf_format =
auto_ptr<log_format>((*iter)->specialized());
found = true;
}
}
}
/* If the scanner didn't match, than we need to add it. */
if (!found) {
logline::level_t last_level = logline::LEVEL_UNKNOWN;
time_t last_time = this->lf_index_time;
short last_millis = 0;
if (!this->lf_index.empty()) {
logline &ll = this->lf_index.back();
/*
* Assume this line is part of the previous one(s) and copy the
* metadata over.
*/
ll.set_multiline();
last_time = ll.get_time();
last_millis = ll.get_millis();
if (this->lf_format.get() != NULL) {
last_level = (logline::level_t)
(ll.get_level() | logline::LEVEL_CONTINUED);
}
}
this->lf_index.push_back(logline(offset,
last_time,
last_millis,
last_level));
}
}
bool logfile::rebuild_index(logfile_observer *lo)
throw (line_buffer::error)
{
bool retval = false;
struct stat st;
if (fstat(this->lf_line_buffer.get_fd(), &st) == -1) {
throw error(this->lf_filename, errno);
}
/* Check for new data based on the file size. */
if (this->lf_index_size < st.st_size) {
off_t last_off, off;
char *line;
size_t len;
this->lf_line_buffer.set_file_size((size_t)-1);
if (this->lf_index.size() > 0) {
off = this->lf_index.back().get_offset();
/*
* Drop the last line we read since it might have been a partial
* read.
*/
this->lf_index.pop_back();
}
else {
off = 0;
}
last_off = off;
while ((line = this->lf_line_buffer.read_line(off, len)) != NULL) {
line[len] = '\0';
this->process_prefix(last_off, line, len);
last_off = off;
if (lo != NULL) {
lo->logfile_indexing(*this, off, st.st_size);
}
}
this->lf_line_buffer.invalidate();
/*
* The file can still grow between the above fstat and when we're
* doing the scanning, so use the line buffer's notion of the file
* size.
*/
this->lf_index_size = this->lf_line_buffer.get_file_size();
retval = true;
}
this->lf_index_time = st.st_mtime;
return retval;
}
void logfile::read_line(logfile::iterator ll, string &line_out)
{
try {
off_t off = ll->get_offset();
const char *line;
size_t len;
line_out.clear();
if ((line = this->lf_line_buffer.read_line(off, len)) != NULL) {
line_out.append(line, len);
}
else {
/* XXX */
}
}
catch (line_buffer::error & e) {
/* ... */
}
}

@ -0,0 +1,173 @@
/**
* @file logfile.hh
*/
#ifndef __logfile_hh
#define __logfile_hh
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <string>
#include <vector>
#include <algorithm>
#include "line_buffer.hh"
#include "log_format.hh"
class logfile;
/**
* Observer interface for logfile indexing progress.
*
* @see logfile
*/
class logfile_observer {
public:
virtual ~logfile_observer() { };
/**
* @param lf The logfile object that is doing the indexing.
* @param off The current offset in the file being processed.
* @param total The total size of the file.
*/
virtual void logfile_indexing(logfile &lf, off_t off, size_t total) = 0;
};
/**
* Container for the lines in a log file and some metadata.
*/
class logfile {
public:
class error {
public:
error(std::string filename, int err)
: e_filename(filename),
e_err(err) { };
std::string e_filename;
int e_err;
};
typedef std::vector<logline>::iterator iterator;
typedef std::vector<logline>::const_iterator const_iterator;
/**
* Construct a logfile with the given arguments.
*
* @param filename The name of the log file.
* @param fd The file descriptor for accessing the file or -1 if the
* constructor should open the file specified by 'filename'. The
* descriptor needs to be seekable.
*/
logfile(std::string filename, auto_fd fd = -1) throw (error);
virtual ~logfile();
/** @return The filename as given in the constructor. */
std::string &get_filename() { return this->lf_filename; };
/**
* @return The detected format, rebuild_index() must be called before this
* will return a value other than FORMAT_UNKNOWN.
*/
log_format *get_format() { return this->lf_format.get(); };
/**
* @return The last modified time of the file when the file was last
* indexed.
*/
time_t get_modified_time() { return this->lf_index_time; };
iterator begin() { return this->lf_index.begin(); }
const_iterator begin() const { return this->lf_index.begin(); }
iterator end() { return this->lf_index.end(); }
const_iterator end() const { return this->lf_index.end(); }
/** @return The number of lines in the index. */
size_t size() { return this->lf_index.size(); }
logline &operator[](int index) { return this->lf_index[index]; };
/**
* Read a line from the file.
*
* @param ll The line to read.
* @param line_out Storage to hold the line itself.
*/
void read_line(iterator ll, std::string &line_out);
/**
* Read a line from the file.
*
* @param ll The line to read.
* @return The contents of the line as a string.
*/
std::string read_line(iterator ll)
{
std::string retval;
this->read_line(ll, retval);
return retval;
};
/**
* Index any new data in the log file.
*
* @param lo The observer object that will be called regularly during
* indexing.
* @return True if any new lines were indexed.
*/
bool rebuild_index(logfile_observer *lo = NULL) throw (line_buffer::error);
bool operator<(const logfile &rhs) const
{
bool retval;
if (this->lf_index.size() == 0) {
retval = true;
}
else if (rhs.lf_index.size() == 0) {
retval = false;
}
else {
retval = this->lf_index[0].get_time() < rhs.lf_index[0].get_time();
}
return retval;
};
/** Check the invariants for this object. */
bool invariant(void)
{
assert(this->lf_filename.size() > 0);
return true;
};
protected:
/**
* Process a line from the file.
*
* @param offset The offset of the line in the file.
* @param prefix The contents of the line.
* @param len The length of the 'prefix' string.
*/
void process_prefix(off_t offset, char *prefix, int len);
std::string lf_filename;
std::auto_ptr<log_format> lf_format;
std::vector<logline> lf_index;
time_t lf_index_time;
size_t lf_index_size;
line_buffer lf_line_buffer;
};
#endif

@ -0,0 +1,18 @@
#ifndef __logfile_hist_hh
#define __logfile_hist_hh
#include <map>
class logfile_hist {
public:
logfile_hist();
virtual ~logfile_hist();
private:
};
#endif

@ -0,0 +1,16 @@
#ifndef __logfile_stats_hh
#define __logfile_stats_hh
class logfile_stats {
public:
logfile_stats();
virtual ~logfile_stats();
private:
};
#endif

@ -0,0 +1,518 @@
#include "config.h"
#include <algorithm>
#include "lnav_util.hh"
#include "logfile_sub_source.hh"
using namespace std;
#if 0
// XXX
class logfile_scrub_map {
public:
static logfile_scrub_map &singleton()
{
static logfile_scrub_map s_lsm;
return s_lsm;
};
const pcre *include(logfile::format_t format) const
{
map<logfile::format_t, pcre *>::const_iterator iter;
pcre *retval = NULL;
if ((iter = this->lsm_include.find(format)) != this->lsm_include.end()) {
retval = iter->second;
}
return retval;
};
const pcre *exclude(logfile::format_t format) const
{
map<logfile::format_t, pcre *>::const_iterator iter;
pcre *retval = NULL;
if ((iter = this->lsm_exclude.find(format)) != this->lsm_exclude.end()) {
retval = iter->second;
}
return retval;
};
private:
pcre *build_pcre(const char *pattern)
{
const char *errptr;
pcre *retval;
int eoff;
retval = pcre_compile(pattern, PCRE_CASELESS, &errptr, &eoff, NULL);
if (retval == NULL) {
throw errptr;
}
return retval;
};
logfile_scrub_map()
{
this->lsm_include[logfile::FORMAT_JBOSS] = this->
build_pcre("\\d+-(\\d+-\\d+ \\d+:\\d+:\\d+),\\d+ [^ ]+( .*)");
this->lsm_exclude[logfile::FORMAT_JBOSS] = this->
build_pcre("(?:"
"\\[((?:[0-9a-zA-Z]+\\.)+)\\w+"
"|\\[[\\w: ]+ ((?:[0-9a-zA-Z]+\\.)+)\\w+[^ \\]]+"
"| ((?:[0-9a-zA-Z]+\\.)+)\\w+\\])");
this->lsm_include[logfile::FORMAT_SYSLOG] = this->
build_pcre("(\\w+\\s[\\s\\d]\\d \\d+:\\d+:\\d+) \\w+( .*)");
};
map<logfile::format_t, pcre *> lsm_include;
map<logfile::format_t, pcre *> lsm_exclude;
};
#endif
bookmark_type_t logfile_sub_source::BM_ERRORS;
bookmark_type_t logfile_sub_source::BM_WARNINGS;
bookmark_type_t logfile_sub_source::BM_FILES;
logfile_sub_source::logfile_sub_source()
: lss_flags(0),
lss_filtered_count(0)
{
}
logfile_sub_source::~logfile_sub_source()
{ }
logfile *logfile_sub_source::find(const char *fn,
content_line_t &line_base)
{
std:: vector<logfile_data>::iterator iter;
logfile *retval = NULL;
line_base = content_line_t(0);
for (iter = this->lss_files.begin();
iter != this->lss_files.end() && retval == NULL;
iter++) {
if (strcmp(iter->ld_file->get_filename().c_str(), fn) == 0) {
retval = iter->ld_file;
}
else {
line_base += content_line_t(iter->ld_file->size());
}
}
return retval;
}
vis_line_t logfile_sub_source::find_from_time(time_t start)
{
vector<content_line_t>::iterator lb;
vis_line_t retval(-1);
lb = lower_bound(this->lss_index.begin(),
this->lss_index.end(),
start,
logline_cmp(*this));
if (lb != this->lss_index.end()) {
retval = vis_line_t(lb - this->lss_index.begin());
}
return retval;
}
void logfile_sub_source::text_value_for_line(textview_curses &tc,
int row,
string &value_out,
bool raw)
{
content_line_t line(0);
size_t tab;
line = this->lss_index[row];
this->lss_token_file = this->find(line);
this->lss_token_line = this->lss_token_file->begin() + line;
this->lss_token_offset = 0;
this->lss_scrub_len = 0;
if (raw) {
this->lss_token_file->read_line(this->lss_token_line, value_out);
return;
}
this->lss_token_value =
this->lss_token_file->read_line(this->lss_token_line);
while ((tab = this->lss_token_value.find('\t')) != string::npos) {
this->lss_token_value = this->lss_token_value.replace(tab, 1, 8, ' ');
}
this->lss_token_date_end = 0;
#if 0
if (!(this->lss_flags & F_NO_SCRUB)) {
log_format *format = this->lss_token_file->get_format();
const pcre *scrubber = NULL;
int matches[60];
int lpc, rc;
// scrubber = logfile_scrub_map::singleton().include(format);
if (scrubber != NULL) {
memset(matches, 0, sizeof(matches));
rc = pcre_exec(logfile_scrub_map::
singleton().include(format),
NULL,
this->lss_token_value.c_str(),
this->lss_token_value.size(),
0,
0,
matches,
60);
matches[1] = 0;
for (lpc = rc - 1; lpc >= 1; lpc--) {
int c_end = matches[lpc * 2];
int c_start = matches[lpc * 2 - 1];
this->lss_token_value.
erase(this->lss_token_value.begin() + c_start,
this->lss_token_value.begin() + c_end);
}
if (rc > 1) {
this->lss_token_date_end = 15;
} /* XXX */
}
scrubber = logfile_scrub_map::singleton().exclude(format);
if (scrubber != NULL) {
do {
rc = pcre_exec(logfile_scrub_map::singleton().
exclude(format),
NULL,
this->lss_token_value.c_str(),
this->lss_token_value.size(),
0,
0,
matches,
60);
for (lpc = rc - 1; lpc >= 1; lpc--) {
int c_start = matches[lpc * 2];
int c_end = matches[lpc * 2 + 1];
if (c_start != -1 && c_end != -1) {
this->lss_token_value.
erase(this->lss_token_value.begin() + c_start,
this->lss_token_value.begin() + c_end);
}
}
} while (rc > 0);
}
}
#endif
value_out = this->lss_token_value;
}
void logfile_sub_source::text_attrs_for_line(textview_curses &lv,
int row,
string_attrs_t &value_out)
{
view_colors &vc = view_colors::singleton();
logline *next_line = NULL;
struct line_range lr;
int attrs = 0;
switch (this->lss_token_line->get_level() & ~logline::LEVEL__FLAGS) {
case logline::LEVEL_CRITICAL:
case logline::LEVEL_ERROR:
attrs = vc.attrs_for_role(view_colors::VCR_ERROR);
break;
case logline::LEVEL_WARNING:
attrs = vc.attrs_for_role(view_colors::VCR_WARNING);
break;
default:
attrs = vc.attrs_for_role(view_colors::VCR_TEXT);
break;
}
if ((row + 1) < (int)this->lss_index.size()) {
next_line = this->find_line(this->lss_index[row + 1]);
}
if (next_line != NULL &&
(day_num(next_line->get_time()) >
day_num(this->lss_token_line->get_time()))) {
attrs |= A_UNDERLINE;
}
lr.lr_start = this->lss_token_date_end;
lr.lr_end = -1;
value_out[lr].insert(make_string_attr("style", attrs));
lr.lr_start = 0;
lr.lr_end = -1;
value_out[lr].insert(make_string_attr("file", this->lss_token_file));
if (this->lss_token_date_end > 0 &&
((this->lss_token_line->get_time() / (60 * 60)) % 2) == 0) {
attrs = vc.attrs_for_role(view_colors::VCR_ALT_ROW);
lr.lr_start = 0;
lr.lr_end = this->lss_token_date_end;
value_out[lr].insert(make_string_attr("style", attrs));
}
}
bool logfile_sub_source::rebuild_index(observer *obs, bool force)
{
std::vector<logfile_data>::iterator iter;
bool retval = force;
for (iter = this->lss_files.begin();
iter != this->lss_files.end();
iter++) {
if (iter->ld_file->rebuild_index(obs)) {
retval = true;
}
if (force) {
iter->ld_lines_indexed = 0;
}
}
if (retval || force) {
int file_index = 0;
string line_value;
line_value.reserve(4 * 1024);
if (force) {
this->lss_index.clear();
this->lss_filtered_count = 0;
}
for (iter = this->lss_files.begin();
iter != this->lss_files.end();
iter++, file_index++) {
if (iter->ld_lines_indexed < iter->ld_file->size()) {
content_line_t con_line(file_index *MAX_LINES_PER_FILE +
iter->ld_lines_indexed);
logfile_filter::type_t action = logfile_filter::INCLUDE;
content_line_t start_line(con_line + 1);
logfile::iterator lf_iter;
int action_priority = -1;
this->lss_index.reserve(this->lss_index.size() +
iter->ld_file->size() -
iter->ld_lines_indexed);
for (lf_iter = iter->ld_file->begin() + iter->ld_lines_indexed;
lf_iter != iter->ld_file->end();
lf_iter++) {
int lpc;
if (obs != NULL) {
obs->logfile_sub_source_filtering(
*this,
content_line_t(con_line % MAX_LINES_PER_FILE),
iter->ld_file->size());
}
if (!(lf_iter->get_level() & logline::LEVEL_CONTINUED)) {
if (action == logfile_filter::INCLUDE ||
action == logfile_filter::MAYBE) {
while (start_line < con_line) {
this->lss_index.push_back(start_line);
++start_line;
}
}
start_line = con_line;
action = logfile_filter::MAYBE;
action_priority = -1;
}
for (lpc = 0; lpc < this->lss_filters.size(); lpc++) {
logfile_filter *filter = this->lss_filters[lpc];
if (filter->is_enabled()) {
bool matched;
if (line_value.empty()) {
iter->ld_file->read_line(lf_iter, line_value);
}
matched = filter->matches(line_value);
switch (filter->get_type()) {
case logfile_filter::INCLUDE:
if (lpc >= action_priority) {
if (matched) {
action = logfile_filter::INCLUDE;
}
else if (action == logfile_filter::MAYBE) {
action = logfile_filter::EXCLUDE;
}
action_priority = lpc;
}
break;
case logfile_filter::EXCLUDE:
if (lpc >= action_priority) {
if (matched) {
action = logfile_filter::EXCLUDE;
}
action_priority = lpc;
}
break;
}
}
}
line_value.clear();
++con_line;
}
if (action == logfile_filter::INCLUDE ||
action == logfile_filter::MAYBE) {
while (start_line < con_line) {
this->lss_index.push_back(start_line);
++start_line;
}
}
iter->ld_lines_indexed = iter->ld_file->size();
assert(iter->ld_lines_indexed < MAX_LINES_PER_FILE);
}
}
stable_sort(this->lss_index.begin(),
this->lss_index.end(),
logline_cmp(*this));
}
return retval;
}
void logfile_sub_source::text_update_marks(bookmarks &bm)
{
logfile *last_file = NULL;
vis_line_t vl;
bm[&BM_WARNINGS].clear();
bm[&BM_ERRORS].clear();
bm[&BM_FILES].clear();
bm[&textview_curses::BM_USER].clear();
for (; vl < this->lss_index.size(); ++vl) {
content_line_t cl = this->lss_index[vl];
logfile *lf;
if (binary_search(this->lss_user_marks.begin(),
this->lss_user_marks.end(),
cl)) {
bm[&textview_curses::BM_USER].insert_once(vl);
}
lf = this->find(cl);
if (lf != last_file) {
bm[&BM_FILES].insert_once(vl);
}
switch ((*lf)[cl].get_level() & ~logline::LEVEL_MULTILINE) {
case logline::LEVEL_WARNING:
bm[&BM_WARNINGS].insert_once(vl);
break;
case logline::LEVEL_ERROR:
case logline::LEVEL_CRITICAL:
bm[&BM_ERRORS].insert_once(vl);
break;
default:
break;
}
last_file = lf;
}
}
#if 0
void logfile_sub_source::handle_scroll(listview_curses *lc)
{
printf("hello, world!\n");
return;
vis_line_t top = lc->get_top();
if (this->lss_index.empty()) {
this->lss_top_time = -1;
this->lss_bottom_time = -1;
}
else {
time_t top_day, bottom_day, today, yesterday, now = time(NULL);
vis_line_t bottom(0), height(0);
unsigned long width;
char status[32];
logline *ll;
today = day_num(now);
yesterday = today - 1;
lc->get_dimensions(height, width);
ll = this->find_line(this->lss_index[top]);
this->lss_top_time = ll->get_time();
bottom = min(top + height - vis_line_t(1),
vis_line_t(this->lss_index.size() - 1));
ll = this->find_line(this->lss_index[bottom]);
this->lss_bottom_time = ll->get_time();
top_day = day_num(this->lss_top_time);
bottom_day = day_num(this->lss_bottom_time);
if (top_day == today) {
snprintf(status, sizeof(status), "Today");
}
else if (top_day == yesterday) {
snprintf(status, sizeof(status), "Yesterday");
}
else {
strftime(status, sizeof(status),
"%a %b %d",
gmtime(&this->lss_top_time));
}
if (top_day != bottom_day) {
int len = strlen(status);
if (bottom_day == today) {
snprintf(&status[len], sizeof(status) - len, " - Today");
}
else if (bottom_day == yesterday) {
snprintf(&status[len], sizeof(status) - len, " - Yesterday");
}
else {
strftime(&status[len], sizeof(status) - len,
" - %b %d",
gmtime(&this->lss_bottom_time));
}
}
this->lss_date_field.set_value(string(status));
}
}
#endif

@ -0,0 +1,225 @@
#ifndef __logfile_controller_hh
#define __logfile_controller_hh
#include <map>
#include <list>
#include <sstream>
#include <vector>
#include <algorithm>
#include "strong_int.hh"
#include "logfile.hh"
#include "bookmarks.hh"
#include "textview_curses.hh"
STRONG_INT_TYPE(int, content_line);
class logfile_filter {
public:
typedef enum {
MAYBE,
INCLUDE,
EXCLUDE
} type_t;
logfile_filter(type_t type, std::string id)
: lf_enabled(true),
lf_type(type),
lf_id(id) { };
virtual ~logfile_filter() { };
type_t get_type(void) const { return this->lf_type; };
std::string get_id(void) const { return this->lf_id; };
bool is_enabled(void) { return this->lf_enabled; };
void enable(void) { this->lf_enabled = true; };
void disable(void) { this->lf_enabled = false; };
virtual bool matches(std::string line) = 0;
protected:
bool lf_enabled;
type_t lf_type;
std::string lf_id;
};
class logfile_sub_source
: public text_sub_source {
public:
typedef std::vector<logfile_filter *> filter_stack_t;
class observer
: public logfile_observer {
public:
virtual void logfile_sub_source_filtering(logfile_sub_source &lss,
content_line_t cl,
size_t total) = 0;
};
static bookmark_type_t BM_ERRORS;
static bookmark_type_t BM_WARNINGS;
static bookmark_type_t BM_FILES;
logfile_sub_source();
virtual ~logfile_sub_source();
filter_stack_t &get_filters(void)
{
return this->lss_filters;
};
logfile_filter *get_filter(std::string id)
{
filter_stack_t::iterator iter;
logfile_filter *retval = NULL;
for (iter = this->lss_filters.begin();
iter != this->lss_filters.end() && (*iter)->get_id() != id;
iter++) { }
if (iter != this->lss_filters.end()) {
retval = *iter;
}
return retval;
};
void toggle_scrub(void) { this->lss_flags ^= F_NO_SCRUB; };
size_t text_line_count()
{
return this->lss_index.size();
};
void text_value_for_line(textview_curses &tc,
int row,
std::string &value_out,
bool raw);
void text_attrs_for_line(textview_curses &tc,
int row,
string_attrs_t &value_out);
void text_user_mark(int line, bool added)
{
content_line_t cl = this->lss_index[line];
std::vector<content_line_t>::iterator lb;
lb = std::lower_bound(this->lss_user_marks.begin(),
this->lss_user_marks.end(),
cl);
if (added) {
this->lss_user_marks.insert(lb, cl);
}
else {
assert(lb != this->lss_user_marks.end());
this->lss_user_marks.erase(lb);
}
};
void insert_file(logfile *lf)
{
assert(lf->size() < MAX_LINES_PER_FILE);
this->lss_files.push_back(logfile_data(lf));
this->lss_index.clear();
};
bool rebuild_index(observer *obs = NULL, bool force = false);
void text_update_marks(bookmarks &bm);
int get_filtered_count() const { return this->lss_filtered_count; };
logfile *find(const char *fn, content_line_t &line_base);
logfile *find(content_line_t &line)
{
logfile *retval;
retval = this->lss_files[line / MAX_LINES_PER_FILE].ld_file;
line = content_line_t(line % MAX_LINES_PER_FILE);
return retval;
};
logline *find_line(content_line_t line)
{
logline *retval = NULL;
logfile *lf = this->find(line);
if (lf != NULL) {
logfile::iterator ll_iter = lf->begin() + line;
retval = &(*ll_iter);
}
return retval;
};
vis_line_t find_from_time(time_t start);
content_line_t at(vis_line_t vl) { return this->lss_index[vl]; };
private:
static const int MAX_LINES_PER_FILE = 16 * 1024 * 1024;
enum {
B_NO_SCRUB,
};
enum {
F_NO_SCRUB = (1L << B_NO_SCRUB),
};
struct logline_cmp {
logline_cmp(logfile_sub_source & lc)
: llss_controller(lc) { };
bool operator()(const content_line_t &lhs, const content_line_t &rhs)
{
logline *ll_lhs = this->llss_controller.find_line(lhs);
logline *ll_rhs = this->llss_controller.find_line(rhs);
return (*ll_lhs) < (*ll_rhs);
};
bool operator()(const content_line_t &lhs, const time_t &rhs)
{
logline *ll_lhs = this->llss_controller.find_line(lhs);
return ll_lhs->get_time() < rhs;
};
logfile_sub_source & llss_controller;
};
struct logfile_data {
logfile_data(logfile *lf = NULL)
: ld_file(lf),
ld_lines_indexed(0) { };
bool operator<(const logfile_data &rhs)
{
return (*this->ld_file) < (*rhs.ld_file);
};
logfile *ld_file;
size_t ld_lines_indexed;
};
unsigned long lss_flags;
std::vector<logfile_data> lss_files;
filter_stack_t lss_filters;
int lss_filtered_count;
std::vector<content_line_t> lss_index;
std::vector<content_line_t> lss_user_marks;
logfile *lss_token_file;
std::string lss_token_value;
int lss_scrub_len;
int lss_token_offset;
int lss_token_date_end;
logfile::iterator lss_token_line;
};
#endif

@ -0,0 +1,151 @@
#ifndef __pcrepp_hh
#define __pcrepp_hh
#ifdef HAVE_PCRE_H
#include <pcre.h>
#elif HAVE_PCRE_PCRE_H
#include <pcre/pcre.h>
#else
#error "pcre.h not found?"
#endif
#include <string>
#include <memory>
#include <exception>
#include "auto_mem.hh"
class pcre_context {
public:
typedef struct {
int m_begin;
int m_end;
int length() { return this->m_end - this->m_begin; };
} match_t;
typedef match_t *iterator;
void set_count(int count) {
this->pc_count = count;
}
match_t *all() { return pc_matches; };
iterator begin() { return pc_matches + 1; };
iterator end() { return pc_matches + pc_count; };
protected:
pcre_context(match_t *matches) : pc_matches(matches) { };
match_t *pc_matches;
int pc_count;
};
template<size_t MAX_COUNT>
class pcre_context_static : public pcre_context {
public:
pcre_context_static()
: pcre_context(this->pc_match_buffer) { };
private:
match_t pc_match_buffer[MAX_COUNT * 3 + 1];
};
class pcre_input {
public:
pcre_input(const char *str, size_t off = 0, size_t len = -1)
: pi_string(str), pi_offset(off), pi_length(len), pi_next_offset(off) {
if (this->pi_length == -1)
this->pi_length = strlen(str);
};
pcre_input(std::string &str, size_t off = 0)
: pi_string(str.c_str()), pi_offset(off), pi_length(str.length()),
pi_next_offset(off) {
};
const char *get_string() const { return this->pi_string; };
const char *get_substr(pcre_context::iterator iter) const {
return &this->pi_string[iter->m_begin];
};
size_t pi_offset;
size_t pi_next_offset;
size_t pi_length;
private:
const char *pi_string;
};
class pcrepp {
public:
class error : public std::exception {
public:
error(std::string msg, int offset) :
e_msg(msg), e_offset(offset) { };
virtual ~error() throw () { };
virtual const char* what() const throw() {
return this->e_msg.c_str();
};
const std::string e_msg;
int e_offset;
};
pcrepp(pcre *code) : p_code(code) {
const char *errptr;
this->p_code_extra = pcre_study(this->p_code, 0, &errptr);
};
pcrepp(const char *pattern, int options = 0) {
const char *errptr;
int eoff;
if ((this->p_code = pcre_compile(pattern,
options,
&errptr,
&eoff,
NULL)) == NULL) {
throw error(errptr, eoff);
}
this->p_code_extra = pcre_study(this->p_code, 0, &errptr);
};
virtual ~pcrepp() { };
bool match(pcre_context &pc, pcre_input &pi, int options = 0) {
int count = 30;
int rc;
pi.pi_offset = pi.pi_next_offset;
rc = pcre_exec(this->p_code,
this->p_code_extra,
pi.get_string(),
pi.pi_length,
pi.pi_offset,
options,
(int *)pc.all(),
count);
if (rc <= 0) { }
else if (pc.all()->m_begin == pc.all()->m_end)
rc = 0;
else
pi.pi_next_offset = pc.all()->m_end;
pc.set_count(rc);
return rc > 0;
};
private:
pcre *p_code;
auto_mem<pcre_extra> p_code_extra;
};
#endif

@ -0,0 +1,65 @@
#include <errno.h>
#include <paths.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include "piper_proc.hh"
using namespace std;
piper_proc::piper_proc(int pipefd)
: pp_fd(-1), pp_child(-1)
{
char piper_tmpname[PATH_MAX];
const char *tmpdir;
if ((tmpdir = getenv("TMPDIR")) == NULL) {
tmpdir = _PATH_VARTMP;
}
snprintf(piper_tmpname, sizeof(piper_tmpname),
"%s/lnav.piper.XXXXXX",
tmpdir);
if ((this->pp_fd = mkstemp(piper_tmpname)) == -1) {
throw error(errno);
}
unlink(piper_tmpname);
this->pp_child = fork();
switch (this->pp_child) {
case -1:
throw error(errno);
case 0:
{
char buffer[4096];
off_t off = 0;
int rc;
while ((rc = read(pipefd, buffer, sizeof(buffer))) > 0) {
int wrc = pwrite(this->pp_fd, buffer, rc, off);
off += wrc;
}
}
exit(0);
break;
default:
break;
}
}
piper_proc::~piper_proc()
{
if (this->pp_child > 0) {
int status;
kill(this->pp_child, SIGTERM);
while (waitpid(this->pp_child, &status, 0) < 0 && (errno == EINTR)) {
;
}
this->pp_child = -1;
}
}

@ -0,0 +1,30 @@
#ifndef __piper_proc_hh
#define __piper_proc_hh
#include <string>
#include <sys/types.h>
class piper_proc {
public:
class error
: public std::exception {
public:
error(int err)
: e_err(err) { };
int e_err;
};
piper_proc(int pipefd);
virtual ~piper_proc();
int get_fd() const { return this->pp_fd; };
private:
std::string pp_filename;
int pp_fd;
pid_t pp_child;
};
#endif

@ -0,0 +1,18 @@
#ifndef __plugins_hh
#define __plugins_hh
#include <string>
class extension_point {
public:
extension_point(std::string name);
~extension_point();
std::string get_name() { return this->ep_name; };
private:
std::string ep_name;
};
#endif

@ -0,0 +1,489 @@
/**
* @file readline_curses.cc
*/
#include "config.h"
#include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#include <string>
#include "auto_mem.hh"
#include "readline_curses.hh"
using namespace std;
static int got_line = 0;
static sig_atomic_t got_timeout = 0;
static sig_atomic_t got_winch = 0;
static readline_curses *child_this;
readline_context *readline_context::loaded_context;
set<string> *readline_context::arg_possibilities;
static void sigalrm(int sig)
{
got_timeout = 1;
}
static void sigwinch(int sig)
{
got_winch = 1;
}
static void line_ready_tramp(char *line)
{
child_this->line_ready(line);
add_history(line);
got_line = 1;
rl_callback_handler_remove();
}
char *readline_context::completion_generator(const char *text, int state)
{
static vector<string> matches;
char *retval = NULL;
if (state == 0) {
int len = strlen(text);
matches.clear();
if (arg_possibilities != NULL) {
set<string>::iterator iter;
for (iter = arg_possibilities->begin();
iter != arg_possibilities->end();
iter++) {
fprintf(stderr, " cmp %s %s\n", text, iter->c_str());
if (strncmp(text, iter->c_str(), len) == 0) {
matches.push_back(*iter);
}
}
}
}
if (!matches.empty()) {
retval = strdup(matches.back().c_str());
matches.pop_back();
}
return retval;
}
char **readline_context::attempted_completion(const char *text,
int start,
int end)
{
char **retval = NULL;
if (start == 0) {
arg_possibilities = &loaded_context->rc_possibilities["__command"];
rl_completion_append_character = ' ';
}
else {
char *space;
string cmd;
rl_completion_append_character = 0;
space = strchr(rl_line_buffer, ' ');
assert(space != NULL);
cmd = string(rl_line_buffer, 0, space - rl_line_buffer);
fprintf(stderr, "cmd %s\n", cmd.c_str());
vector<string> &proto = loaded_context->rc_prototypes[cmd];
if (proto.size() == 0) {
arg_possibilities = NULL;
}
else if (proto[0] == "filename") {
return NULL; // XXX
}
else {
fprintf(stderr, "proto %s\n", proto[0].c_str());
arg_possibilities = &(loaded_context->rc_possibilities[proto[0]]);
fprintf(stderr, "ag %p %d\n",
arg_possibilities,
arg_possibilities->size());
}
}
retval = rl_completion_matches(text, completion_generator);
if (retval == NULL) {
rl_attempted_completion_over = 1;
}
return retval;
}
readline_curses::readline_curses()
: rc_active_context(-1),
rc_child(-1)
{
struct winsize ws;
int sp[2];
if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sp) < 0) {
throw error(errno);
}
this->rc_command_pipe[RCF_MASTER] = sp[RCF_MASTER];
this->rc_command_pipe[RCF_SLAVE] = sp[RCF_SLAVE];
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) {
throw error(errno);
}
if (openpty(this->rc_pty[RCF_MASTER].out(),
this->rc_pty[RCF_SLAVE].out(),
NULL,
NULL,
&ws) < 0) {
throw error(errno);
}
if ((this->rc_child = fork()) == -1) {
throw error(errno);
}
if (this->rc_child == 0) {
char buffer[1024];
this->rc_command_pipe[RCF_MASTER].reset();
this->rc_pty[RCF_MASTER].reset();
signal(SIGALRM, sigalrm);
signal(SIGWINCH, sigwinch);
dup2(this->rc_pty[RCF_SLAVE], STDIN_FILENO);
dup2(this->rc_pty[RCF_SLAVE], STDOUT_FILENO);
setenv("TERM", "vt52", 1);
rl_initialize();
/*
* XXX Need to keep the input on a single line since the display screws
* up if it wraps around.
*/
strcpy(buffer, "set horizontal-scroll-mode on");
rl_parse_and_bind(buffer); // NOTE: buffer is modified
child_this = this;
}
else {
this->rc_command_pipe[RCF_SLAVE].reset();
this->rc_pty[RCF_SLAVE].reset();
}
}
readline_curses::~readline_curses()
{
if (this->rc_child == 0) {
exit(0);
}
else if (this->rc_child > 0) {
int status;
kill(this->rc_child, SIGTERM);
this->rc_child = -1;
while (wait(&status) < 0 && (errno == EINTR)) {
;
}
}
}
void readline_curses::start(void)
{
if (this->rc_child != 0) {
return;
}
map<int, readline_context *>::iterator current_context;
fd_set rfds;
int maxfd;
assert(!this->rc_contexts.empty());
rl_completer_word_break_characters = (char *)" \t\n"; /* XXX */
current_context = this->rc_contexts.end();
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
FD_SET(this->rc_command_pipe[RCF_SLAVE], &rfds);
maxfd = max(STDIN_FILENO, this->rc_command_pipe[RCF_SLAVE].get());
while (1) {
fd_set ready_rfds = rfds;
int rc;
rc = select(maxfd + 1, &ready_rfds, NULL, NULL, NULL);
if (rc < 0) {
switch (errno) {
case EINTR:
break;
}
}
else {
if (FD_ISSET(STDIN_FILENO, &ready_rfds)) {
struct itimerval itv;
assert(current_context != this->rc_contexts.end());
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = KEY_TIMEOUT;
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
rl_callback_read_char();
if (RL_ISSTATE(RL_STATE_DONE) && !got_line) {
got_line = 1;
this->line_ready("");
rl_callback_handler_remove();
}
/* fprintf(stderr, " is done: %d\n", RL_ISSTATE(RL_STATE_DONE)); */
}
if (FD_ISSET(this->rc_command_pipe[RCF_SLAVE], &ready_rfds)) {
char msg[1024 + 1];
/* fprintf(stderr, "rl cmd\n"); */
if ((rc = read(this->rc_command_pipe[RCF_SLAVE],
msg,
sizeof(msg) - 1)) < 0) {
fprintf(stderr, "read\n");
}
else {
int context, prompt_start = 0;
char type[32];
msg[rc] = '\0';
if (sscanf(msg, "f:%d:%n", &context, &prompt_start) == 1 &&
prompt_start != 0 &&
(current_context = this->rc_contexts.find(context)) !=
this->rc_contexts.end()) {
current_context->second->load();
rl_callback_handler_install(&msg[prompt_start],
line_ready_tramp);
}
else if (sscanf(msg,
"ap:%d:%31[^:]:%n",
&context,
type,
&prompt_start) == 2) {
assert(this->rc_contexts[context] != NULL);
this->rc_contexts[context]->
add_possibility(string(type),
string(&msg[prompt_start]));
}
else if (sscanf(msg,
"rp:%d:%31[^:]:%n",
&context,
type,
&prompt_start) == 2) {
assert(this->rc_contexts[context] != NULL);
this->rc_contexts[context]->
rem_possibility(string(type),
string(&msg[prompt_start]));
}
else {
fprintf(stderr, "unhandled message: %s\n", msg);
}
}
}
}
if (got_timeout) {
char msg[1024];
fprintf(stderr, "got timeout\n");
got_timeout = 0;
snprintf(msg, sizeof(msg), "t:%s", rl_line_buffer);
write(this->rc_command_pipe[RCF_SLAVE], msg, strlen(msg));
}
if (got_line) {
struct itimerval itv;
got_line = 0;
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 0;
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 0;
if (setitimer(ITIMER_REAL, &itv, NULL) < 0) {
fprintf(stderr, "setitimer");
}
current_context->second->save();
current_context = this->rc_contexts.end();
}
if (got_winch) {
struct winsize ws;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) {
throw error(errno);
}
fprintf(stderr, "rl winched %d %d\n", ws.ws_row, ws.ws_col);
got_winch = 0;
rl_set_screen_size(ws.ws_row, ws.ws_col);
}
}
}
void readline_curses::line_ready(const char *line)
{
auto_mem<char> expanded;
char msg[1024];
int rc;
rc = history_expand(rl_line_buffer, expanded.out());
switch (rc) {
#if 0
// TODO: fix clash between history and pcre metacharacters
case - 1:
/* XXX */
snprintf(msg, sizeof(msg),
"e:unable to expand history -- %s",
expanded.in());
break;
#endif
case -1:
snprintf(msg, sizeof(msg), "d:%s", line);
break;
case 0:
case 1:
case 2: /* XXX */
snprintf(msg, sizeof(msg), "d:%s", expanded.in());
break;
}
write(this->rc_command_pipe[RCF_SLAVE], msg, strlen(msg));
}
void readline_curses::check_fd_set(fd_set &ready_rfds)
{
int rc;
if (FD_ISSET(this->rc_pty[RCF_MASTER], &ready_rfds)) {
char buffer[128];
rc = read(this->rc_pty[RCF_MASTER], buffer, sizeof(buffer));
assert(rc != 0);
assert(rc != -1 && (errno != EINTR || errno != EIO));
{
int lpc;
fprintf(stderr, "from child %d|", rc);
for (lpc = 0; lpc < rc; lpc++) {
fprintf(stderr, " %d", buffer[lpc]);
}
fprintf(stderr, "\n");
}
this->map_output(buffer, rc);
}
if (FD_ISSET(this->rc_command_pipe[RCF_MASTER], &ready_rfds)) {
char msg[1024 + 1];
rc = read(this->rc_command_pipe[RCF_MASTER], msg, sizeof(msg) - 1);
assert(rc != 0);
if (rc >= 2) {
string old_value = this->rc_value;
msg[rc] = '\0';
fprintf(stderr, "child command: %s\n", msg);
this->rc_value = string(&msg[2]);
switch (msg[0]) {
case 't':
if (this->rc_value != old_value) {
this->rc_timeout.invoke(this);
}
break;
case 'd':
fprintf(stderr, "done!\n");
this->rc_active_context = -1;
this->vc_past_lines.clear();
this->rc_perform.invoke(this);
break;
}
}
}
}
void readline_curses::handle_key(int ch)
{
const char *bch;
int len;
bch = this->map_input(ch, len);
write(this->rc_pty[RCF_MASTER], bch, len);
fprintf(stderr, "to child %d\n", bch[0]);
if (ch == '\t' || ch == '\r') {
this->vc_past_lines.clear();
}
}
void readline_curses::focus(int context, const char *prompt)
{
char buffer[1024];
this->rc_active_context = context;
snprintf(buffer, sizeof(buffer), "f:%d:%s", context, prompt);
write(this->rc_command_pipe[RCF_MASTER], buffer, strlen(buffer) + 1);
wmove(this->vc_window, this->get_actual_y(), 0);
wclrtoeol(this->vc_window);
}
void readline_curses::add_possibility(int context, string type, string value)
{
char buffer[1024];
snprintf(buffer, sizeof(buffer),
"ap:%d:%s:%s",
context, type.c_str(), value.c_str());
write(this->rc_command_pipe[RCF_MASTER], buffer, strlen(buffer) + 1);
}
void readline_curses::rem_possibility(int context, string type, string value)
{
char buffer[1024];
snprintf(buffer, sizeof(buffer),
"rp:%d:%s:%s",
context, type.c_str(), value.c_str());
write(this->rc_command_pipe[RCF_MASTER], buffer, strlen(buffer) + 1);
}
void readline_curses::do_update(void)
{
if (this->rc_active_context == -1) {
mvwprintw(this->vc_window, this->get_actual_y(), 0,
"%s",
this->rc_value.c_str());
wclrtoeol(this->vc_window);
this->set_x(0);
}
vt52_curses::do_update();
}

@ -0,0 +1,175 @@
/**
* @file readline_curses.hh
*/
#ifndef __readline_curses_hh
#define __readline_curses_hh
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <exception>
#include <readline/readline.h>
#include <readline/history.h>
#include "auto_fd.hh"
#include "vt52_curses.hh"
class readline_context {
public:
typedef std::string (*command_t)(std::string cmdline,
std::vector<std::string> &args);
typedef std::map<std::string, command_t> command_map_t;
readline_context(command_map_t *commands = NULL)
{
if (commands != NULL) {
command_map_t::iterator iter;
for (iter = commands->begin(); iter != commands->end(); iter++) {
std::string cmd = iter->first;
this->rc_possibilities["__command"].insert(cmd);
iter->second(cmd, this->rc_prototypes[cmd]);
}
}
memset(&this->rc_history, 0, sizeof(this->rc_history));
};
void load(void)
{
loaded_context = this;
rl_attempted_completion_function = attempted_completion;
history_set_history_state(&this->rc_history);
};
void save(void)
{
HISTORY_STATE *hs = history_get_history_state();
this->rc_history = *hs;
free(hs);
hs = NULL;
};
void add_possibility(std::string type, std::string value)
{
this->rc_possibilities[type].insert(value);
fprintf(stderr, "pos %d %p %s %s\n",
this->rc_possibilities[type].size(),
&this->rc_possibilities[type],
type.c_str(),
value.c_str());
};
void rem_possibility(std::string type, std::string value)
{
this->rc_possibilities[type].erase(value);
};
private:
static char **attempted_completion(const char *text, int start, int end);
static char *completion_generator(const char *text, int state);
static readline_context *loaded_context;
static std:: set<std::string> *arg_possibilities;
HISTORY_STATE rc_history;
std::map<std::string, std::set<std::string> > rc_possibilities;
std::map<std::string, std::vector<std::string> > rc_prototypes;
};
class readline_curses
: public vt52_curses {
public:
typedef view_action<readline_curses> action;
class error
: public std::exception {
public:
error(int err)
: e_err(err) { };
int e_err;
};
static const int KEY_TIMEOUT = 750 * 1000;
readline_curses();
virtual ~readline_curses();
void add_context(int id, readline_context &rc)
{
this->rc_contexts[id] = &rc;
};
void set_perform_action(action va) { this->rc_perform = va; };
void set_timeout_action(action va) { this->rc_timeout = va; };
void set_value(std::string value) { this->rc_value = value; };
std::string get_value() { return this->rc_value; };
int update_fd_set(fd_set &readfds)
{
FD_SET(this->rc_pty[RCF_MASTER], &readfds);
FD_SET(this->rc_command_pipe[RCF_MASTER], &readfds);
return std::max(this->rc_pty[RCF_MASTER].get(),
this->rc_command_pipe[RCF_MASTER].get());
};
void handle_key(int ch);
void check_fd_set(fd_set &ready_rfds);
void focus(int context, const char *prompt);
void start(void);
void do_update(void);
void window_change(void)
{
struct winsize ws;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) {
throw error(errno);
}
if (ioctl(this->rc_pty[RCF_MASTER], TIOCSWINSZ, &ws) == -1) {
throw error(errno);
}
};
void line_ready(const char *line);
void add_possibility(int context, std::string type, std::string value);
void rem_possibility(int context, std::string type, std::string value);
private:
enum {
RCF_MASTER,
RCF_SLAVE,
RCF_MAX_VALUE,
};
int rc_active_context;
pid_t rc_child;
auto_fd rc_pty[2];
auto_fd rc_command_pipe[2];
std::map<int, readline_context *> rc_contexts;
std::string rc_value;
action rc_perform;
action rc_timeout;
};
#endif

@ -0,0 +1,8 @@
#ifndef __status_controllers_hh
#define __status_controllers_hh
#include "listview_curses.hh"
#include "statusview_curses.hh"
#endif

@ -0,0 +1,48 @@
#include "config.h"
#include "statusview_curses.hh"
using namespace std;
void statusview_curses::do_update(void)
{
int top, attrs, field, field_count, left = 1, right;
view_colors &vc = view_colors::singleton();
unsigned long width, height;
getmaxyx(this->sc_window, height, width);
top = this->sc_top < 0 ? height + this->sc_top : this->sc_top;
right = width - 2;
attrs = vc.attrs_for_role(view_colors::VCR_STATUS);
wattron(this->sc_window, attrs);
wmove(this->sc_window, top, 0);
wclrtoeol(this->sc_window);
whline(this->sc_window, ' ', width);
wattroff(this->sc_window, attrs);
field_count = this->sc_source->statusview_fields();
for (field = 0; field < field_count; field++) {
status_field &sf = this->sc_source->statusview_value_for_field(field);
struct line_range lr = { 0, sf.get_width() };
attr_line_t val;
string str;
int x;
val = sf.get_value();
if (sf.is_right_justified()) {
right -= 1 + sf.get_width();
x = right;
}
else {
x = left;
left += sf.get_width() + 1;
}
this->mvwattrline(this->sc_window,
top, x,
val,
lr,
sf.get_role());
}
wmove(this->sc_window, top + 1, 0);
}

@ -0,0 +1,162 @@
/**
* @file statusview_curses.hh
*/
#ifndef __statusview_curses_hh
#define __statusview_curses_hh
#include <curses.h>
#include <string>
#include <vector>
#include "view_curses.hh"
/**
* Container for individual status values.
*/
class status_field {
public:
/**
* @param width The maximum width of the field in characters.
* @param role The color role for this field, defaults to VCR_STATUS.
*/
status_field(int width = 1,
view_colors::role_t role = view_colors::VCR_STATUS)
: sf_width(width),
sf_right_justify(false),
sf_cylon(false),
sf_cylon_pos(0),
sf_role(role) { };
virtual ~status_field() { };
/** @param value The new value for this field. */
void set_value(std::string value) {
if (value.size() > this->get_width()) {
if (value.size() <= 11) {
value.resize(11);
}
else {
static const std::string MIDSUB = " .. ";
size_t half_width = this->get_width() / 2 - MIDSUB.size() / 2;
std::string abbrev;
abbrev.append(value, 0, half_width);
abbrev.append(MIDSUB);
abbrev.append(value,
value.size() - half_width,
std::string::npos);
value = abbrev;
}
}
this->sf_value = value;
string_attrs_t &sa = this->sf_value.get_attrs();
sa.clear();
if (this->sf_cylon) {
struct line_range lr = { this->sf_cylon_pos,
this->sf_width };
sa[lr].insert(make_string_attr("style", COLOR_PAIR(view_colors::VC_WHITE_ON_GREEN) | A_BOLD));
this->sf_cylon_pos += 1;
if (this->sf_cylon_pos > this->sf_width)
this->sf_cylon_pos = 0;
}
};
/**
* Set the new value for this field using a formatted string.
*
* @param fmt The format string.
* @param ... Arguments for the format.
*/
void set_value(const char *fmt, ...)
{
char buffer[128];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
this->set_value(std::string(buffer));
va_end(args);
};
/** @return The string value for this field. */
attr_line_t &get_value() { return this->sf_value; };
void right_justify(bool yes) { this->sf_right_justify = yes; };
bool is_right_justified(void) { return this->sf_right_justify; };
void set_cylon(bool yes) { this->sf_cylon = yes; };
bool is_cylon(void) { return this->sf_cylon; };
/** @return True if this field's value is an empty string. */
bool empty() { return this->sf_value.get_string().empty(); };
void clear() { this->sf_value.clear(); };
/** @param role The color role for this field. */
void set_role(view_colors::role_t role) { this->sf_role = role; };
/** @return The color role for this field. */
view_colors::role_t get_role() { return this->sf_role; };
/** @param width The maximum display width, in characters. */
void set_width(int width) { this->sf_width = width; };
/** @param width The maximum display width, in characters. */
int get_width() { return this->sf_width; };
protected:
int sf_width; /*< The maximum display width, in chars. */
bool sf_right_justify;
bool sf_cylon;
int sf_cylon_pos;
attr_line_t sf_value; /*< The value to display for this field. */
view_colors::role_t sf_role; /*< The color role for this field. */
};
class telltale_field : public status_field {
public:
};
class status_data_source {
public:
virtual ~status_data_source() { };
virtual size_t statusview_fields(void) = 0;
virtual status_field &statusview_value_for_field(int field) = 0;
};
class statusview_curses
: public view_curses {
public:
statusview_curses()
: sc_window(NULL),
sc_top(0) { };
virtual ~statusview_curses() { };
void set_data_source(status_data_source *src) { this->sc_source = src; };
status_data_source *get_data_source() { return this->sc_source; };
void set_top(int top) { this->sc_top = top; };
int get_top() { return this->sc_top; };
void set_window(WINDOW *win) { this->sc_window = win; };
WINDOW *get_window() { return this->sc_window; };
void do_update(void);
private:
status_data_source *sc_source;
WINDOW *sc_window;
int sc_top;
};
#endif

@ -0,0 +1,61 @@
/**
* @file strong_int.hh
*/
#ifndef __strong_int_hh
#define __strong_int_hh
/**
* Template class for "strongly-typed" integers, in other words, integers that
* have different semantic meaning and cannot be easily used in place of one
* another.
*
* @param T The integer type.
* @param DISTINCT An class used solely to distinguish templates that have the
* same integer type.
*/
template<typename T, class DISTINCT>
class strong_int {
public:
explicit strong_int(T v = 0) : value(v) { };
operator const T & () const { return this->value; };
strong_int operator+(const strong_int &rhs) {
return strong_int(this->value + rhs.value);
};
strong_int operator-(const strong_int &rhs) {
return strong_int(this->value - rhs.value);
};
strong_int operator/(const strong_int &rhs) {
return strong_int(this->value / rhs.value);
};
strong_int &operator+=(const strong_int &rhs) {
this->value += rhs.value;
return *this;
};
strong_int &operator-=(const strong_int &rhs) {
this->value -= rhs.value;
return *this;
};
strong_int &operator-(void) {
this->value = -this->value;
return *this;
};
strong_int &operator++(void) { this->value++; return *this; };
strong_int &operator--(void) { this->value--; return *this; };
T *out(void) { return &this->value; };
private:
T value;
};
/**
* Macro that declares a strongly-typed integer and the empty class used as a
* distinguisher.
*
* @param T The integer type.
* @param name The name of the strongly-typed integer.
*/
#define STRONG_INT_TYPE(T, name) \
class __##name##_distinct; \
typedef strong_int<int, __##name##_distinct> name##_t
#endif

@ -0,0 +1,63 @@
#ifndef __tables_h
#define __tables_h
#define __table_str( x ) #x
#define __table_section( table, idx ) \
__section__ ( ".tbl." __table_str ( table ) "." __table_str ( idx ) )
#define __table_section_start( table ) __table_section ( table, 00 )
#define __table_section_end( table ) __table_section ( table, 99 )
#define __natural_alignment( type ) __aligned__ ( __alignof__ ( type ) )
/**
* Linker table entry.
*
* Declares a data structure to be part of a linker table. Use as
* e.g.
*
* @code
*
* struct my_foo __table ( foo, 01 ) = {
* ...
* };
*
* @endcode
*
*/
#define __table( type, table, idx ) \
__attribute__ (( __table_section ( table, idx ), \
__natural_alignment ( type ) ))
/**
* Linker table start marker.
*
* Declares a data structure (usually an empty data structure) to be
* the start of a linker table. Use as e.g.
*
* @code
*
* static struct foo_start[0] __table_start ( foo );
*
* @endcode
*
*/
#define __table_start( type, table ) __table ( type, table, 00 )
/**
* Linker table end marker.
*
* Declares a data structure (usually an empty data structure) to be
* the end of a linker table. Use as e.g.
*
* @code
*
* static struct foo_end[0] __table_end ( foo );
*
* @endcode
*
*/
#define __table_end( type, table ) __table ( type, table, 99 )
#endif

@ -0,0 +1,260 @@
#include "config.h"
#include <algorithm>
#include "lnav_util.hh"
#include "textview_curses.hh"
using namespace std;
bookmark_type_t textview_curses::BM_USER;
bookmark_type_t textview_curses::BM_SEARCH;
class ansi_scrubber {
/* XXX move to view_curses.cc ; actually, move to it's own file and call
* from there.
*/
public:
static ansi_scrubber &singleton()
{
static ansi_scrubber s_as;
return s_as;
}
void scrub_value(string &str, string_attrs_t &sa)
{
int rc, matches[60];
do {
rc = pcre_exec(this->as_pcre,
NULL,
str.c_str(),
str.size(),
0,
0,
matches,
60);
if (rc > 0) {
int c_start = matches[0];
int c_end = matches[1];
struct line_range lr;
bool has_attrs = false;
int attrs = 0;
int lpc;
switch (str[matches[4]]) {
case 'm':
for (lpc = matches[2]; lpc != string::npos && lpc < matches[3];) {
int ansi_code = 0;
if (sscanf(&(str[lpc]), "%d", &ansi_code) == 1) {
switch (ansi_code) {
case 1:
attrs |= A_BOLD;
break;
case 2:
attrs |= A_DIM;
break;
case 4:
attrs |= A_UNDERLINE;
break;
case 7:
attrs |= A_REVERSE;
break;
case 31:
attrs |= COLOR_PAIR(view_colors::VC_RED);
break;
case 32:
attrs |= COLOR_PAIR(view_colors::VC_GREEN);
break;
case 33:
attrs |= COLOR_PAIR(view_colors::VC_YELLOW);
break;
case 34:
attrs |= COLOR_PAIR(view_colors::VC_BLUE);
break;
case 35:
attrs |= COLOR_PAIR(view_colors::VC_MAGENTA);
break;
case 36:
attrs |= COLOR_PAIR(view_colors::VC_CYAN);
break;
case 37:
attrs |= COLOR_PAIR(view_colors::VC_WHITE);
break;
}
}
lpc = str.find(";", lpc);
if (lpc != string::npos) {
lpc += 1;
}
}
has_attrs = true;
break;
case 'C':
{
int spaces = 0;
if (sscanf(&(str[matches[2]]), "%d", &spaces) == 1) {
str.insert(c_end, spaces, ' ');
}
}
break;
}
str.erase(str.begin() + c_start, str.begin() + c_end);
if (has_attrs) {
lr.lr_start = c_start;
lr.lr_end = -1;
sa[lr].insert(make_string_attr("style", attrs));
}
}
} while (rc > 0);
};
private:
pcre *build_pcre(const char *pattern) /* XXX refactor me */
{
const char *errptr;
pcre *retval;
int eoff;
retval = pcre_compile(pattern, 0, &errptr, &eoff, NULL);
if (retval == NULL) {
throw errptr;
}
return retval;
};
ansi_scrubber()
{
this->as_pcre = this->build_pcre("\x1b\\[([\\d=;]*)([a-zA-Z])");
};
pcre *as_pcre;
};
textview_curses::textview_curses()
: tc_searching(false),
tc_follow_search(false)
{
this->set_data_source(this);
}
textview_curses::~textview_curses()
{ }
void textview_curses::reload_data(void)
{
if (this->tc_sub_source != NULL) {
this->tc_sub_source->text_update_marks(this->tc_bookmarks);
}
this->listview_curses::reload_data();
}
void textview_curses::grep_begin(grep_proc &gp)
{
this->tc_searching = true;
this->tc_match_count = 0;
this->tc_bookmarks[&BM_SEARCH].clear();
this->tc_search_action.invoke(this);
listview_curses::reload_data();
}
void textview_curses::grep_end(grep_proc &gp)
{
this->tc_searching = false;
this->tc_search_action.invoke(this);
}
void textview_curses::grep_match(grep_proc &gp,
grep_line_t line,
int start,
int end)
{
this->tc_match_count += 1;
this->tc_bookmarks[&BM_SEARCH].insert_once(vis_line_t(line));
listview_curses::reload_data();
}
void textview_curses::listview_value_for_row(const listview_curses &lv,
vis_line_t row,
attr_line_t &value_out)
{
bookmark_vector &bv = this->tc_bookmarks[&BM_USER];
string_attrs_t &sa = value_out.get_attrs();
string &str = value_out.get_string();
highlight_map_t::iterator iter;
string::iterator str_iter;
this->tc_sub_source->text_value_for_line(*this, row, str);
this->tc_sub_source->text_attrs_for_line(*this, row, sa);
ansi_scrubber::singleton().scrub_value(str, sa);
for (iter = this->tc_highlights.begin();
iter != this->tc_highlights.end();
iter++) {
int off, hcount = 0;
for (off = 0; off < str.size(); ) {
int rc, matches[30];
rc = pcre_exec(iter->second.h_code,
NULL,
str.c_str(),
str.size(),
off,
0,
matches,
30);
if (rc > 0) {
struct line_range lr;
if (rc == 2) {
lr.lr_start = matches[2];
lr.lr_end = matches[3];
}
else {
lr.lr_start = matches[0];
lr.lr_end = matches[1];
}
if (lr.lr_end > lr.lr_start) {
sa[lr].insert(make_string_attr("style", iter->second.
get_attrs(hcount)));
hcount++;
off = matches[1];
}
else {
off += 1;
}
}
else {
off = str.size();
}
}
}
if (binary_search(bv.begin(), bv.end(), row)) {
string_attrs_t::iterator iter;
for (iter = sa.begin(); iter != sa.end(); iter++) {
attrs_map_t &am = iter->second;
attrs_map_t::iterator am_iter;
for (am_iter = am.begin(); am_iter != am.end(); am_iter++) {
if (am_iter->first == "style") {
am_iter->second.sa_int ^= A_REVERSE;
}
}
}
}
}

@ -0,0 +1,218 @@
#ifndef __textview_curses_hh
#define __textview_curses_hh
#include <vector>
#include "grep_proc.hh"
#include "bookmarks.hh"
#include "listview_curses.hh"
class textview_curses;
class text_sub_source {
public:
virtual ~text_sub_source() { };
virtual void toggle_scrub(void) { };
virtual size_t text_line_count() = 0;
virtual void text_value_for_line(textview_curses &tc,
int line,
std::string &value_out,
bool raw = false) = 0;
virtual void text_attrs_for_line(textview_curses &tc,
int line,
string_attrs_t &value_out) {
};
virtual void text_update_marks(bookmarks &bm) { };
virtual void text_user_mark(int line, bool added) { };
};
class textview_curses
: public listview_curses,
public list_data_source,
public grep_proc_source,
public grep_proc_sink {
public:
typedef view_action<textview_curses> action;
static bookmark_type_t BM_USER;
static bookmark_type_t BM_SEARCH;
struct highlighter {
highlighter()
: h_code(NULL),
h_multiple(false) { };
highlighter(pcre *code,
bool multiple = false,
view_colors::role_t role = view_colors::VCR_NONE)
: h_code(code),
h_multiple(multiple)
{
if (!multiple) {
if (role == view_colors::VCR_NONE) {
this->h_roles.
push_back(view_colors::singleton().next_highlight());
}
else {
this->h_roles.push_back(role);
}
}
};
view_colors::role_t get_role(int index)
{
view_colors &vc = view_colors::singleton();
view_colors::role_t retval;
if (this->h_multiple) {
while (index >= this->h_roles.size()) {
this->h_roles.push_back(vc.next_highlight());
}
retval = this->h_roles[index];
}
else {
retval = this->h_roles[0];
}
return retval;
};
int get_attrs(int index)
{
return view_colors::singleton().
attrs_for_role(this->get_role(index));
};
pcre *h_code;
bool h_multiple;
std::vector<view_colors::role_t> h_roles;
};
textview_curses();
virtual ~textview_curses();
bookmarks &get_bookmarks(void) { return this->tc_bookmarks; };
void toggle_user_mark(int start_line, int end_line = -1)
{
if (end_line == -1)
end_line = start_line;
for (int curr_line = start_line; curr_line <= end_line; curr_line++) {
bookmark_vector &bv = this->tc_bookmarks[&BM_USER];
bookmark_vector::iterator iter;
bool added = false;
iter = bv.insert_once(vis_line_t(curr_line));
if (iter == bv.end()) {
added = true;
}
else {
bv.erase(iter);
}
this->tc_sub_source->text_user_mark(curr_line, added);
}
};
void set_sub_source(text_sub_source *src)
{
this->tc_sub_source = src;
this->reload_data();
};
text_sub_source *get_sub_source(void) { return this->tc_sub_source; };
void set_search_action(action sa) { this->tc_search_action = sa; };
template<class _Receiver>
void set_search_action(action::mem_functor_t < _Receiver > *mf)
{
this->tc_search_action = action(mf);
};
void grep_end_batch(grep_proc &gp)
{
if (this->tc_follow_search && !this->tc_bookmarks[&BM_SEARCH].empty()) {
vis_line_t first_hit;
first_hit = this->tc_bookmarks[&BM_SEARCH].
next(vis_line_t(this->get_top() - 1));
if (first_hit != -1) {
if (first_hit > 0) {
--first_hit;
}
this->set_top(first_hit);
}
}
this->tc_search_action.invoke(this);
};
void grep_end(grep_proc &gp);
size_t listview_rows(const listview_curses &lv)
{
return this->tc_sub_source == NULL ? 0 :
this->tc_sub_source->text_line_count();
};
void listview_value_for_row(const listview_curses &lv,
vis_line_t line,
attr_line_t &value_out);
bool grep_value_for_line(int line, std::string &value_out)
{
bool retval = false;
if (line < this->tc_sub_source->text_line_count()) {
this->tc_sub_source->text_value_for_line(*this,
line,
value_out,
true);
retval = true;
}
return retval;
};
void grep_begin(grep_proc &gp);
void grep_match(grep_proc &gp,
grep_line_t line,
int start,
int end);
bool is_searching(void) { return this->tc_searching; };
void set_follow_search(bool fs) { this->tc_follow_search = fs; };
size_t get_match_count(void)
{
return this->tc_match_count;
};
typedef std::map<std::string, highlighter> highlight_map_t;
highlight_map_t &get_highlights() { return this->tc_highlights; };
void reload_data(void);
protected:
text_sub_source *tc_sub_source;
bookmarks tc_bookmarks;
vis_line_t tc_lview_top;
int tc_lview_left;
int tc_match_count;
bool tc_searching;
bool tc_follow_search;
action tc_search_action;
highlight_map_t tc_highlights;
highlight_map_t::iterator tc_current_highlight;
};
#endif

@ -0,0 +1,22 @@
#ifndef __time_t_hh
#define __time_t_hh
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#define timeit(_block) { \
struct timeval _st, _en, _diff; \
\
gettimeofday(&_st, NULL); \
{ _block; } \
gettimeofday(&_en, NULL); \
timersub(&_en, &_st, &_diff); \
fprintf(stderr, \
"%s %d.%06d\n", \
#_block, _diff.tv_sec, _diff.tv_usec); \
fflush(stderr); \
}
#endif

@ -0,0 +1,121 @@
#ifndef _top_status_source_hh
#define _top_status_source_hh
#include <string>
#include "logfile_sub_source.hh"
#include "statusview_curses.hh"
class top_status_source
: public status_data_source
{
public:
typedef listview_curses::action::mem_functor_t<
top_status_source> lv_functor_t;
typedef textview_curses::action::mem_functor_t<
top_status_source> tv_functor_t;
typedef enum {
TSF_TIME,
TSF_WARNINGS,
TSF_ERRORS,
TSF_FILENAME,
TSF__MAX
} field_t;
top_status_source()
: marks_wire(*this, &top_status_source::update_marks),
filename_wire(*this, &top_status_source::update_filename) {
this->tss_fields[TSF_TIME].set_width(24);
this->tss_fields[TSF_WARNINGS].set_width(10);
this->tss_fields[TSF_ERRORS].set_width(10);
this->tss_fields[TSF_ERRORS].set_role(view_colors::VCR_ALERT_STATUS);
this->tss_fields[TSF_FILENAME].set_width(35); // XXX
this->tss_fields[TSF_FILENAME].right_justify(true);
};
lv_functor_t marks_wire;
lv_functor_t filename_wire;
size_t statusview_fields(void) { return TSF__MAX; };
status_field &statusview_value_for_field(int field) {
return this->tss_fields[field];
};
void update_time(void) {
status_field &sf = this->tss_fields[TSF_TIME];
time_t current_time = time(NULL);
char buffer[32];
strftime(buffer, sizeof(buffer),
"%a %b %d %H:%M:%S %Z",
localtime(&current_time));
sf.set_value(buffer);
};
void update_marks(listview_curses *lc) {
textview_curses *tc = dynamic_cast<textview_curses *>(lc);
status_field &sfw = this->tss_fields[TSF_WARNINGS];
status_field &sfe = this->tss_fields[TSF_ERRORS];
bookmarks &bm = tc->get_bookmarks();
unsigned long width;
vis_line_t height;
tc->get_dimensions(height, width);
if (bm.find(&logfile_sub_source::BM_WARNINGS) != bm.end()) {
bookmark_vector &bv = bm[&logfile_sub_source::BM_WARNINGS];
bookmark_vector::iterator iter;
iter = lower_bound(bv.begin(), bv.end(), tc->get_top());
sfw.set_value("%9dW", distance(bv.begin(), iter));
}
else {
sfw.clear();
}
if (bm.find(&logfile_sub_source::BM_ERRORS) != bm.end()) {
bookmark_vector &bv = bm[&logfile_sub_source::BM_ERRORS];
bookmark_vector::iterator iter;
iter = lower_bound(bv.begin(), bv.end(), tc->get_top());
sfe.set_value("%9dE", distance(bv.begin(), iter));
}
else {
sfe.clear();
}
};
void update_filename(listview_curses *lc) {
if (lc->get_inner_height() > 0) {
status_field &sf = this->tss_fields[TSF_FILENAME];
struct line_range lr = { 0, -1 };
attrs_map_t::iterator iter;
string_attrs_t sa;
attr_line_t al;
lc->get_data_source()->
listview_value_for_row(*lc, lc->get_top(), al);
sa = al.get_attrs();
iter = sa[lr].find("file");
if (iter != sa[lr].end()) {
logfile *lf = (logfile *)iter->second.sa_ptr;
sf.set_value(lf->get_filename());
}
else {
sf.clear();
}
}
};
private:
status_field tss_fields[TSF__MAX];
};
#endif

@ -0,0 +1,53 @@
#ifndef _top_sys_status_source_hh
#define _top_sys_status_source_hh
#include <string>
#include "logfile_sub_source.hh"
#include "statusview_curses.hh"
class top_sys_status_source
: public status_data_source
{
public:
typedef enum {
TSF_CPU,
TSF_MEM,
TSF_TRAF,
TSF__MAX
} field_t;
top_sys_status_source() {
static std::string names[TSF__MAX] = {
"#CPU",
"#Mem",
"#Traf",
};
int lpc;
for (lpc = 0; lpc < TSF__MAX; lpc++) {
this->tss_fields[lpc].set_width(5);
this->tss_fields[lpc].set_value(names[lpc]);
}
this->tss_fields[TSF_CPU].set_role(view_colors::VCR_WARN_STATUS);
this->tss_fields[TSF_MEM].set_role(view_colors::VCR_ALERT_STATUS);
this->tss_fields[TSF_TRAF].set_role(view_colors::VCR_ACTIVE_STATUS);
};
size_t statusview_fields(void) { return TSF__MAX; };
status_field &statusview_value_for_field(int field) {
return this->tss_fields[field];
};
private:
telltale_field tss_fields[TSF__MAX];
};
#endif

@ -0,0 +1,178 @@
/**
* @file view_curses.cc
*/
#include "config.h"
#include <string>
#include "view_curses.hh"
using namespace std;
void view_curses::mvwattrline(WINDOW *window,
int y,
int x,
attr_line_t &al,
struct line_range &lr,
view_colors::role_t base_role)
{
int text_attrs, attrs, line_width;
string_attrs_t &sa = al.get_attrs();
string &line = al.get_string();
string_attrs_t::iterator iter;
char *buffer;
line_width = lr.length();
buffer = (char *)alloca(line_width + 1);
{
size_t tab;
while ((tab = line.find('\t')) != string::npos) {
line = line.replace(tab, 1, 8, ' ');
}
while ((tab = line.find('\r')) != string::npos) {
line = line.replace(tab, 1, " ");
}
}
text_attrs = view_colors::singleton().attrs_for_role(base_role);
attrs = text_attrs;
wmove(window, y, x);
wattron(window, attrs);
if (lr.lr_start < (int)line.size()) {
waddnstr(window, &line.c_str()[lr.lr_start], line_width);
}
if (lr.lr_end > line.size())
whline(window, ' ', lr.lr_end - line.size());
wattroff(window, attrs);
for (iter = sa.begin(); iter != sa.end(); iter++) {
struct line_range attr_range = iter->first;
assert(attr_range.lr_start >= 0);
assert(attr_range.lr_end >= -1);
attr_range.lr_start = max(0, attr_range.lr_start - lr.lr_start);
if (attr_range.lr_end == -1) {
attr_range.lr_end = line_width;
}
else {
attr_range.lr_end = min((int)line_width,
attr_range.lr_end - lr.lr_start);
}
if (attr_range.lr_end > 0) {
int awidth = attr_range.length();
attrs_map_t &am = iter->second;
attrs_map_t::iterator am_iter;
attrs = 0;
for (am_iter = am.begin(); am_iter != am.end(); am_iter++) {
if (am_iter->first == "style") {
attrs |= am_iter->second.sa_int;
}
}
/* This silliness is brought to you by a buggy old curses lib. */
mvwinnstr(window, y, x + attr_range.lr_start, buffer, awidth);
wattron(window, attrs);
mvwaddnstr(window, y, x + attr_range.lr_start, buffer, awidth);
wattroff(window, attrs);
}
attrs = text_attrs; /* Reset attrs to regular text. */
}
}
view_colors &view_colors::singleton(void)
{
static view_colors s_vc;
return s_vc;
}
view_colors::view_colors()
: vc_next_highlight(0)
{
int lpc;
/* Setup the mappings from roles to actual colors. */
this->vc_role_colors[VCR_TEXT] = COLOR_PAIR(VC_WHITE) | A_DIM;
this->vc_role_colors[VCR_SEARCH] =
this->vc_role_colors[VCR_TEXT] | A_REVERSE;
this->vc_role_colors[VCR_OK] = COLOR_PAIR(VC_GREEN) | A_BOLD;
this->vc_role_colors[VCR_ERROR] = COLOR_PAIR(VC_RED) | A_BOLD;
this->vc_role_colors[VCR_WARNING] = COLOR_PAIR(VC_YELLOW) | A_BOLD;
this->vc_role_colors[VCR_ALT_ROW] = COLOR_PAIR(VC_WHITE) | A_BOLD;
this->vc_role_colors[VCR_STATUS] =
COLOR_PAIR(VC_BLACK_ON_WHITE);
this->vc_role_colors[VCR_WARN_STATUS] =
COLOR_PAIR(VC_YELLOW_ON_WHITE) | A_BOLD;
this->vc_role_colors[VCR_ALERT_STATUS] =
COLOR_PAIR(VC_RED_ON_WHITE);
this->vc_role_colors[VCR_ACTIVE_STATUS] =
COLOR_PAIR(VC_GREEN_ON_WHITE);
this->vc_role_colors[VCR_ACTIVE_STATUS2] =
COLOR_PAIR(VC_GREEN_ON_WHITE) | A_BOLD;
for (lpc = 0; lpc < VCR__MAX; lpc++) {
this->vc_role_reverse_colors[lpc] =
this->vc_role_colors[lpc] | A_REVERSE;
}
/*
* Prime the highlight vector. The first HL_COLOR_COUNT color pairs are
* assumed to be the highlight colors.
*/
for (lpc = 1; lpc <= HL_COLOR_COUNT; lpc++) {
this->vc_role_colors[VCR__MAX + (lpc - 1) * 2] = COLOR_PAIR(lpc);
this->vc_role_colors[VCR__MAX + (lpc - 1) * 2 + 1] =
COLOR_PAIR(lpc) | A_BOLD;
this->vc_role_reverse_colors[VCR__MAX + (lpc - 1) * 2] =
COLOR_PAIR(lpc + HL_COLOR_COUNT) | A_REVERSE;
this->vc_role_reverse_colors[VCR__MAX + (lpc - 1) * 2 + 1] =
COLOR_PAIR(lpc) | A_BOLD | A_REVERSE;
}
}
void view_colors::init(void)
{
if (has_colors()) {
start_color();
/* use_default_colors(); */
init_pair(VC_BLUE, COLOR_BLUE, COLOR_BLACK);
init_pair(VC_CYAN, COLOR_CYAN, COLOR_BLACK);
init_pair(VC_GREEN, COLOR_GREEN, COLOR_BLACK);
init_pair(VC_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);
init_pair(VC_BLUE_ON_WHITE, COLOR_BLUE, COLOR_WHITE);
init_pair(VC_CYAN_ON_BLACK, COLOR_CYAN, COLOR_BLACK);
init_pair(VC_GREEN_ON_WHITE, COLOR_GREEN, COLOR_WHITE);
init_pair(VC_MAGENTA_ON_WHITE, COLOR_MAGENTA, COLOR_WHITE);
init_pair(VC_RED, COLOR_RED, COLOR_BLACK);
init_pair(VC_YELLOW, COLOR_YELLOW, COLOR_BLACK);
init_pair(VC_WHITE, COLOR_WHITE, COLOR_BLACK);
init_pair(VC_BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE);
init_pair(VC_RED_ON_WHITE, COLOR_RED, COLOR_WHITE);
init_pair(VC_YELLOW_ON_WHITE, COLOR_YELLOW, COLOR_WHITE);
init_pair(VC_WHITE_ON_GREEN, COLOR_WHITE, COLOR_GREEN);
}
}
view_colors::role_t view_colors::next_highlight(void)
{
role_t retval = (role_t)(VCR__MAX + this->vc_next_highlight);
this->vc_next_highlight = (this->vc_next_highlight + 1) %
(HL_COLOR_COUNT * 2);
return retval;
}

@ -0,0 +1,344 @@
/**
* @file view_curses.hh
*/
#ifndef __view_curses_hh
#define __view_curses_hh
#include <assert.h>
#include <stdint.h>
#include <ncurses.h>
#include <map>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
class view_curses;
class screen_curses {
public:
screen_curses()
: sc_main_window(initscr()) { };
virtual ~screen_curses() { endwin(); };
WINDOW *get_window() { return this->sc_main_window; };
private:
WINDOW *sc_main_window;
};
struct line_range {
int lr_start;
int lr_end;
int length() const {
return this->lr_end == -1 ? INT_MAX : this->lr_end - this->lr_start;
};
bool operator<(const struct line_range &rhs) const {
if (this->lr_start < rhs.lr_start) return true;
else if (this->lr_start > rhs.lr_start) return false;
if (this->lr_end < rhs.lr_end) return true;
return false;
};
};
typedef union {
void *sa_ptr;
int sa_int;
} string_attr_t;
inline std::pair<std::string, string_attr_t>
make_string_attr(const std::string name, void *val)
{
string_attr_t sa;
sa.sa_ptr = val;
return std::make_pair(name, sa);
}
inline std::pair<std::string, string_attr_t>
make_string_attr(const std::string name, int val)
{
string_attr_t sa;
sa.sa_int = val;
return std::make_pair(name, sa);
}
typedef std::multimap<std::string, string_attr_t> attrs_map_t;
typedef std::map<struct line_range, attrs_map_t> string_attrs_t;
class attr_line_t {
public:
attr_line_t() { };
std::string &get_string() { return this->al_string; };
string_attrs_t &get_attrs() { return this->al_attrs; };
void operator=(const std::string &rhs) { this->al_string = rhs; };
void clear() {
this->al_string.clear();
this->al_attrs.clear();
};
private:
std::string al_string;
string_attrs_t al_attrs;
};
/**
* Class that encapsulates a method to execute and the object on which to
* execute it.
*
* @param _Sender The type of object that will be triggering an action.
*/
template<class _Sender>
class view_action {
public:
/**
*
* @param _Receiver The type of object that will be triggered by an action.
*/
template<class _Receiver>
class mem_functor_t {
public:
mem_functor_t(_Receiver &receiver,
void (_Receiver::*selector)(_Sender *))
: mf_receiver(receiver),
mf_selector(selector) { };
void operator()(_Sender *sender)
{
(this->mf_receiver.*mf_selector)(sender);
};
static void invoke(mem_functor_t *self, _Sender *sender)
{
(*self)(sender);
};
private:
_Receiver & mf_receiver;
void (_Receiver::*mf_selector)(_Sender *);
};
class broadcaster
: public std::vector<view_action> {
public:
broadcaster()
: b_functor(*this, &broadcaster::invoke) { };
virtual ~broadcaster() { };
void invoke(_Sender *sender)
{
typename std::vector<view_action>::iterator iter;
for (iter = this->begin(); iter != this->end(); iter++) {
(*iter).invoke(sender);
}
};
mem_functor_t<broadcaster> *get_functor()
{
return &this->b_functor;
};
private:
mem_functor_t<broadcaster> b_functor;
};
/**
* @param receiver The object to pass as the first argument to the selector
* function.
* @param selector The function to execute. The function should take two
* parameters, the first being the value of the receiver pointer and the
* second being the sender pointer as passed to invoke().
*/
view_action(void (*invoker)(void *, _Sender *) = NULL)
: va_functor(NULL),
va_invoker(invoker) { };
template<class _Receiver>
view_action(mem_functor_t < _Receiver > *mf)
: va_functor(mf),
va_invoker((void (*)(void *, _Sender *))
mem_functor_t<_Receiver>::invoke) { };
/**
* Performs a shallow copy of another view_action.
*
* @param va The view_action to copy the receiver and selector pointers
* from.
*/
view_action(const view_action &va)
: va_functor(va.va_functor),
va_invoker(va.va_invoker) { };
~view_action() { };
/**
* @param rhs The view_action to shallow copy.
* @return *this
*/
view_action &operator=(const view_action &rhs)
{
this->va_functor = rhs.va_functor;
this->va_invoker = rhs.va_invoker;
return *this;
};
/**
* Invoke the action by calling the selector function, if one is set.
*
* @param sender Pointer to the object that called this method.
*/
void invoke(_Sender *sender)
{
if (this->va_invoker != NULL) {
this->va_invoker(this->va_functor, sender);
}
};
private:
/** The object to pass as the first argument to the selector function.*/
void *va_functor;
/** The function to call when this action is invoke()'d. */
void (*va_invoker)(void *functor, _Sender * sender);
};
/**
* Singleton used to manage the colorspace.
*/
class view_colors {
public:
/** Roles that can be mapped to curses attributes using attrs_for_role() */
typedef enum {
VCR_NONE = -1,
VCR_TEXT, /*< Raw text. */
VCR_SEARCH, /*< A search hit. */
VCR_OK,
VCR_ERROR, /*< An error message. */
VCR_WARNING, /*< A warning message. */
VCR_ALT_ROW, /*< Highlight for alternating rows in a list */
VCR_STATUS, /*< Normal status line text. */
VCR_WARN_STATUS,
VCR_ALERT_STATUS, /*< Alert status line text. */
VCR_ACTIVE_STATUS, /*< */
VCR_ACTIVE_STATUS2, /*< */
VCR__MAX
} role_t;
/** @return A reference to the singleton. */
static view_colors &singleton();
/**
* Performs curses-specific initialization. The other methods can be
* called before this method, but the returned attributes cannot be used
* with curses code until this method is called.
*/
void init(void);
/**
* @param role The role to retrieve character attributes for.
* @return The attributes to use for the given role.
*/
int attrs_for_role(role_t role)
{
assert(role >= 0);
assert(role < VCR__MAX + (HL_COLOR_COUNT * 2));
return this->vc_role_colors[role];
};
int reverse_attrs_for_role(role_t role)
{
assert(role >= 0);
assert(role < VCR__MAX + (HL_COLOR_COUNT * 2));
return this->vc_role_reverse_colors[role];
};
/**
* @return The next set of attributes to use for highlighting text. This
* method will iterate through eight-or-so attributes combinations so there
* is some variety in how text is highlighted.
*/
role_t next_highlight(void);
enum {
VC_EMPTY = 0, /* XXX Dead color pair, doesn't work. */
VC_BLUE,
VC_CYAN,
VC_GREEN,
VC_MAGENTA,
VC_BLUE_ON_WHITE,
VC_CYAN_ON_BLACK,
VC_GREEN_ON_WHITE,
VC_MAGENTA_ON_WHITE,
VC_RED,
VC_YELLOW,
VC_WHITE,
VC_BLACK_ON_WHITE,
VC_YELLOW_ON_WHITE,
VC_RED_ON_WHITE,
VC_WHITE_ON_GREEN,
};
private:
/** The number of colors used for highlighting. */
static const int HL_COLOR_COUNT = 4;
/** Private constructor that initializes the member fields. */
view_colors();
/** Map of role IDs to attribute values. */
int vc_role_colors[VCR__MAX + (HL_COLOR_COUNT * 2)];
/** Map of role IDs to reverse-video attribute values. */
int vc_role_reverse_colors[VCR__MAX + (HL_COLOR_COUNT * 2)];
/** The index of the next highlight color to use. */
int vc_next_highlight;
};
/**
* Interface for "view" classes that will update a curses(3) display.
*/
class view_curses {
public:
virtual ~view_curses() { };
/**
* Update the curses display.
*/
virtual void do_update(void) = 0;
void mvwattrline(WINDOW *window,
int y,
int x,
attr_line_t &al,
struct line_range &lr,
view_colors::role_t base_role = view_colors::VCR_TEXT);
};
#endif

@ -0,0 +1,238 @@
/**
* @file vt52_curses.cc
*/
#include "config.h"
#include <assert.h>
#include <curses.h>
#include <unistd.h>
#include <map>
#include "vt52_curses.hh"
using namespace std;
/**
* Singleton used to hold the mapping of ncurses keycodes to VT52 escape
* sequences.
*/
class vt52_escape_map {
public:
/** @return The singleton. */
static vt52_escape_map &singleton()
{
static vt52_escape_map s_vem;
return s_vem;
};
/**
* @param ch The ncurses keycode.
* @return The null terminated VT52 escape sequence.
*/
const char *operator[](int ch) const
{
map < int, const char * >::const_iterator iter;
const char *retval = NULL;
if ((iter = this->vem_map.find(ch)) != this->vem_map.end()) {
retval = iter->second;
}
return retval;
};
const char *operator[](const char *seq) const
{
map < string, const char * >::const_iterator iter;
const char *retval = NULL;
assert(seq != NULL);
if ((iter = this->vem_input_map.find(seq)) !=
this->vem_input_map.end()) {
retval = iter->second;
}
return retval;
};
private:
/** Construct the map with a few escape sequences. */
vt52_escape_map()
{
static char area_buffer[1024];
char *area = area_buffer;
if (tgetent(NULL, "vt52") == ERR) {
perror("tgetent");
}
this->vem_map[KEY_UP] = tgetstr("ku", &area);
this->vem_map[KEY_DOWN] = tgetstr("kd", &area);
this->vem_map[KEY_RIGHT] = tgetstr("kr", &area);
this->vem_map[KEY_LEFT] = tgetstr("kl", &area);
this->vem_map[KEY_HOME] = tgetstr("kh", &area);
this->vem_map[KEY_BACKSPACE] = "\010";
this->vem_map[KEY_DC] = "\x4";
this->vem_map[KEY_BEG] = "\x1";
this->vem_map[KEY_END] = "\x5";
this->vem_map[KEY_SLEFT] = tgetstr("#4", NULL);
if (this->vem_map[KEY_SLEFT] == NULL) {
this->vem_map[KEY_SLEFT] = "\033b";
}
this->vem_map[KEY_SRIGHT] = tgetstr("%i", NULL);
if (this->vem_map[KEY_SRIGHT] == NULL) {
this->vem_map[KEY_SRIGHT] = "\033f";
}
this->vem_input_map[tgetstr("ce", &area)] = "ce";
this->vem_input_map[tgetstr("kl", &area)] = "kl";
tgetent(NULL, getenv("TERM"));
};
/** Map of ncurses keycodes to VT52 escape sequences. */
map < int, const char * > vem_map;
map < string, const char * > vem_input_map;
};
vt52_curses::vt52_curses()
: vc_window(NULL),
vc_x(0),
vc_y(0),
vc_escape_len(0)
{ }
vt52_curses::~vt52_curses()
{ }
const char *vt52_curses::map_input(int ch, int &len_out)
{
const char *esc, *retval;
/* Check for an escape sequence, otherwise just return the char. */
if ((esc = vt52_escape_map::singleton()[ch]) != NULL) {
retval = esc;
len_out = strlen(retval);
}
else {
this->vc_map_buffer = (char)ch;
retval = &this->vc_map_buffer;/* XXX probably shouldn't do this. */
len_out = 1;
}
assert(retval != NULL);
assert(len_out > 0);
return retval;
}
void vt52_curses::map_output(const char *output, int len)
{
int y, lpc;
assert(this->vc_window != NULL);
y = this->get_actual_y();
wmove(this->vc_window, y, this->vc_x);
for (lpc = 0; lpc < len; lpc++) {
if (this->vc_escape_len > 0) {
const char *cap;
this->vc_escape[this->vc_escape_len] = output[lpc];
this->vc_escape_len += 1;
this->vc_escape[this->vc_escape_len] = '\0';
if ((cap = vt52_escape_map::singleton()[this->vc_escape]) != NULL) {
if (strcmp(cap, "ce") == 0) {
wclrtoeol(this->vc_window);
this->vc_escape_len = 0;
}
else if (strcmp(cap, "kl") == 0) {
this->vc_x -= 1;
wmove(this->vc_window, y, this->vc_x);
this->vc_escape_len = 0;
}
}
}
else {
switch (output[lpc]) {
case STX:
this->vc_past_lines.clear();
this->vc_x = 0;
wmove(this->vc_window, y, this->vc_x);
wclrtoeol(this->vc_window);
break;
case BELL:
flash();
break;
case BACKSPACE:
this->vc_x -= 1;
wmove(this->vc_window, y, this->vc_x);
break;
case ESCAPE:
this->vc_escape[0] = ESCAPE;
this->vc_escape_len = 1;
break;
case '\n':
{
unsigned long width, height;
char *buffer;
getmaxyx(this->vc_window, height, width);
buffer = (char *)alloca(width);
this->vc_x = 0;
wmove(this->vc_window, y, this->vc_x);
/*
* XXX Not sure why we need to subtract one from the width
* here, but otherwise it seems to spill over and screw up
* the next line when we're writing it back out in
* do_update().
*/
winnstr(this->vc_window, buffer, width - 1);
this->vc_past_lines.push_back(buffer);
wclrtoeol(this->vc_window);
}
break;
case '\r':
this->vc_x = 0;
wmove(this->vc_window, y, this->vc_x);
break;
default:
mvwaddch(this->vc_window, y, this->vc_x, output[lpc]);
this->vc_x += 1;
break;
}
}
}
}
void vt52_curses::do_update(void)
{
list<string>::iterator iter;
int y;
y = this->get_actual_y() - (int)this->vc_past_lines.size();
for (iter = this->vc_past_lines.begin();
iter != this->vc_past_lines.end();
iter++, y++) {
if (y >= 0) {
mvwprintw(this->vc_window, y, 0, "%s", iter->c_str());
wclrtoeol(this->vc_window);
}
}
wmove(this->vc_window, y, this->vc_x);
}

@ -0,0 +1,134 @@
/**
* @file vt52_curses.hh
*/
#ifndef __vt52_curses_hh
#define __vt52_curses_hh
#include <curses.h>
#include <term.h>
#undef set_window /* XXX term.h #defines this... */
#include <list>
#include <string>
#include "view_curses.hh"
/**
* VT52 emulator for curses, useful for mediating between curses and readline,
* which don't play well together. It is expected that a subclass of this
* class will fork off a child process that sends and receives VT52 keycodes(?)
* which is translated by this class into curses calls.
*
* VT52 seems to be the simplest terminal to emulate since we do not need to
* maintain the state of the screen, beyond past lines. For example, when
* inserting a character, VT52 moves the cursor to the insertion point, clears
* the rest of the line and then rewrites the rest of the line with the new
* character. This is in contrast to VT100 which moves the cursor to the
* insertion point and then sends a code to insert the character and relying
* on the terminal to shift the rest of the line to the right a character.
*/
class vt52_curses
: public view_curses {
public:
vt52_curses();
virtual ~vt52_curses();
/** @param win The curses window this view is attached to. */
void set_window(WINDOW *win) { this->vc_window = win; };
/** @return The curses window this view is attached to. */
WINDOW *get_window() { return this->vc_window; };
/**
* Set the Y position of this view on the display. A value greater than
* zero is considered to be an absolute size. A value less than zero makes
* the position relative to the bottom of the enclosing window.
*
* @param y The Y position of the cursor on the curses display.
*/
void set_y(int y) { this->vc_y = y; };
/** @return The abs/rel Y position of the cursor on the curses display. */
int get_y() { return this->vc_y; };
/** @param x The X position of the cursor on the curses display. */
void set_x(int x) { this->vc_x = x; };
/** @return The X position of the cursor on the curses display. */
int get_x() { return this->vc_x; };
/**
* @return The height of this view, which consists of a single line for
* input, plus any past lines of output, which will appear ABOVE the Y
* position for this view.
* @todo Kinda hardwired to the way readline works.
*/
int get_height() { return this->vc_past_lines.size() + 1; };
void set_max_height(int mh) { this->vc_max_height = mh; };
int get_max_height() { return this->vc_max_height; };
/**
* Map an ncurses input keycode to a vt52 sequence.
*
* @param ch The input character.
* @param len_out The length of the returned sequence.
* @return The vt52 sequence to send to the child.
*/
const char *map_input(int ch, int &len_out);
/**
* Map VT52 output to ncurses calls.
*
* @param output VT52 encoded output from the child process.
* @param len The length of the output array.
*/
void map_output(const char *output, int len);
/**
* Paints any past lines and moves the cursor to the current X position.
*/
void do_update(void);
const static char ESCAPE = 27; /*< VT52 Escape key value. */
const static char BACKSPACE = 8; /*< VT52 Backspace key value. */
const static char BELL = 7; /*< VT52 Bell value. */
const static char STX = 2; /*< VT52 Start-of-text value. */
protected:
/** @return The absolute Y position of this view. */
int get_actual_y()
{
unsigned long width, height;
int retval;
getmaxyx(this->vc_window, height, width);
if (this->vc_y < 0) {
retval = height + this->vc_y;
}
else {
retval = this->vc_y;
}
return retval;
};
WINDOW *vc_window; /*< The window that contains this view. */
int vc_x; /*< The X position of the cursor. */
int vc_y; /*< The Y position of the cursor. */
int vc_max_height;
char vc_escape[16]; /*< Storage for escape sequences. */
int vc_escape_len; /*< The number of chars in vc_escape. */
char vc_map_buffer; /*<
* Buffer returned by map_input for trivial
* translations (one-to-one).
*/
/** Vector of past lines of output from the child. */
std::list<std::string> vc_past_lines;
};
#endif

@ -0,0 +1,119 @@
TESTS_ENVIRONMENT = $(SHELL) $(top_builddir)/TESTS_ENVIRONMENT
AM_CPPFLAGS = \
-I$(top_srcdir)/src \
$(SQLITE3_CFLAGS) \
$(SOCI_CXXFLAGS)
# AM_CFLAGS = -fprofile-arcs -ftest-coverage
# AM_CXXFLAGS = -fprofile-arcs -ftest-coverage
if HAVE_SOCI
SOCI_TESTS =
else
SOCI_TESTS =
endif
check_PROGRAMS = \
drive_line_buffer \
drive_grep_proc \
drive_listview \
drive_logfile \
drive_vt52_curses \
drive_readline_curses \
slicer \
scripty \
test_auto_fd \
test_auto_mem \
test_bookmarks \
test_grep_proc2 \
$(SOCI_TESTS) \
test_line_buffer2 \
test_top_status
AM_LDFLAGS = \
$(SQLITE3_LDFLAGS)
LDADD = -lz
test_auto_fd_SOURCES = test_auto_fd.cc
test_auto_mem_SOURCES = test_auto_mem.cc
test_bookmarks_SOURCES = test_bookmarks.cc ../src/bookmarks.cc
test_grep_proc2_SOURCES = \
../src/line_buffer.cc \
../src/grep_proc.cc \
test_grep_proc2.cc
test_grep_proc2_LDADD = $(PCRE_LIBS) -lz
test_line_buffer2_SOURCES = \
../src/line_buffer.cc \
test_line_buffer2.cc
test_top_status_SOURCES = \
../src/bookmarks.cc \
../src/logfile.cc \
../src/line_buffer.cc \
../src/log_format.cc \
../src/logfile_sub_source.cc \
../src/listview_curses.cc \
../src/textview_curses.cc \
../src/view_curses.cc \
test_top_status.cc
test_top_status_LDADD = $(CURSES_LIB) -lz
drive_line_buffer_SOURCES = \
../src/line_buffer.cc \
drive_line_buffer.cc
drive_line_buffer_LDADD = $(CURSES_LIB) -lz
drive_grep_proc_SOURCES = \
../src/line_buffer.cc \
../src/grep_proc.cc \
drive_grep_proc.cc
drive_grep_proc_LDADD = $(PCRE_LIBS) -lz
drive_listview_SOURCES = \
../src/listview_curses.cc \
../src/view_curses.cc \
drive_listview.cc
drive_listview_LDADD = $(CURSES_LIB) -lz
drive_logfile_SOURCES = \
../src/logfile.cc \
../src/log_format.cc \
../src/line_buffer.cc \
drive_logfile.cc
drive_vt52_curses_SOURCES = \
../src/vt52_curses.cc \
drive_vt52_curses.cc
drive_vt52_curses_LDADD = $(CURSES_LIB)
drive_readline_curses_SOURCES = \
../src/vt52_curses.cc \
../src/readline_curses.cc \
drive_readline_curses.cc
drive_readline_curses_LDADD = $(CURSES_LIB) $(READLINE_LIBS)
slicer_SOURCES = \
../src/line_buffer.cc \
slicer.cc
scripty_SOURCES = scripty.cc
TESTS = test_bookmarks \
test_auto_fd \
test_auto_mem \
test_line_buffer.sh \
test_line_buffer2 \
test_grep_proc.sh \
test_grep_proc2 \
$(SOCI_TESTS) \
test_listview.sh \
test_logfile.sh \
test_vt52_curses.sh \
test_top_status

@ -0,0 +1,867 @@
# Makefile.in generated by automake 1.10.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008 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@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@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@
check_PROGRAMS = drive_line_buffer$(EXEEXT) drive_grep_proc$(EXEEXT) \
drive_listview$(EXEEXT) drive_logfile$(EXEEXT) \
drive_vt52_curses$(EXEEXT) drive_readline_curses$(EXEEXT) \
slicer$(EXEEXT) scripty$(EXEEXT) test_auto_fd$(EXEEXT) \
test_auto_mem$(EXEEXT) test_bookmarks$(EXEEXT) \
test_grep_proc2$(EXEEXT) $(am__EXEEXT_1) \
test_line_buffer2$(EXEEXT) test_top_status$(EXEEXT)
TESTS = test_bookmarks$(EXEEXT) test_auto_fd$(EXEEXT) \
test_auto_mem$(EXEEXT) test_line_buffer.sh \
test_line_buffer2$(EXEEXT) test_grep_proc.sh \
test_grep_proc2$(EXEEXT) $(am__EXEEXT_1) test_listview.sh \
test_logfile.sh test_vt52_curses.sh test_top_status$(EXEEXT)
subdir = test
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/ax_sqlite3.m4 \
$(top_srcdir)/lnav.m4 $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
am__EXEEXT_1 =
am_drive_grep_proc_OBJECTS = line_buffer.$(OBJEXT) grep_proc.$(OBJEXT) \
drive_grep_proc.$(OBJEXT)
drive_grep_proc_OBJECTS = $(am_drive_grep_proc_OBJECTS)
am__DEPENDENCIES_1 =
drive_grep_proc_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_drive_line_buffer_OBJECTS = line_buffer.$(OBJEXT) \
drive_line_buffer.$(OBJEXT)
drive_line_buffer_OBJECTS = $(am_drive_line_buffer_OBJECTS)
drive_line_buffer_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_drive_listview_OBJECTS = listview_curses.$(OBJEXT) \
view_curses.$(OBJEXT) drive_listview.$(OBJEXT)
drive_listview_OBJECTS = $(am_drive_listview_OBJECTS)
drive_listview_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_drive_logfile_OBJECTS = logfile.$(OBJEXT) log_format.$(OBJEXT) \
line_buffer.$(OBJEXT) drive_logfile.$(OBJEXT)
drive_logfile_OBJECTS = $(am_drive_logfile_OBJECTS)
drive_logfile_LDADD = $(LDADD)
drive_logfile_DEPENDENCIES =
am_drive_readline_curses_OBJECTS = vt52_curses.$(OBJEXT) \
readline_curses.$(OBJEXT) drive_readline_curses.$(OBJEXT)
drive_readline_curses_OBJECTS = $(am_drive_readline_curses_OBJECTS)
drive_readline_curses_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am_drive_vt52_curses_OBJECTS = vt52_curses.$(OBJEXT) \
drive_vt52_curses.$(OBJEXT)
drive_vt52_curses_OBJECTS = $(am_drive_vt52_curses_OBJECTS)
drive_vt52_curses_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_scripty_OBJECTS = scripty.$(OBJEXT)
scripty_OBJECTS = $(am_scripty_OBJECTS)
scripty_LDADD = $(LDADD)
scripty_DEPENDENCIES =
am_slicer_OBJECTS = line_buffer.$(OBJEXT) slicer.$(OBJEXT)
slicer_OBJECTS = $(am_slicer_OBJECTS)
slicer_LDADD = $(LDADD)
slicer_DEPENDENCIES =
am_test_auto_fd_OBJECTS = test_auto_fd.$(OBJEXT)
test_auto_fd_OBJECTS = $(am_test_auto_fd_OBJECTS)
test_auto_fd_LDADD = $(LDADD)
test_auto_fd_DEPENDENCIES =
am_test_auto_mem_OBJECTS = test_auto_mem.$(OBJEXT)
test_auto_mem_OBJECTS = $(am_test_auto_mem_OBJECTS)
test_auto_mem_LDADD = $(LDADD)
test_auto_mem_DEPENDENCIES =
am_test_bookmarks_OBJECTS = test_bookmarks.$(OBJEXT) \
bookmarks.$(OBJEXT)
test_bookmarks_OBJECTS = $(am_test_bookmarks_OBJECTS)
test_bookmarks_LDADD = $(LDADD)
test_bookmarks_DEPENDENCIES =
am_test_grep_proc2_OBJECTS = line_buffer.$(OBJEXT) grep_proc.$(OBJEXT) \
test_grep_proc2.$(OBJEXT)
test_grep_proc2_OBJECTS = $(am_test_grep_proc2_OBJECTS)
test_grep_proc2_DEPENDENCIES = $(am__DEPENDENCIES_1)
am_test_line_buffer2_OBJECTS = line_buffer.$(OBJEXT) \
test_line_buffer2.$(OBJEXT)
test_line_buffer2_OBJECTS = $(am_test_line_buffer2_OBJECTS)
test_line_buffer2_LDADD = $(LDADD)
test_line_buffer2_DEPENDENCIES =
am_test_top_status_OBJECTS = bookmarks.$(OBJEXT) logfile.$(OBJEXT) \
line_buffer.$(OBJEXT) log_format.$(OBJEXT) \
logfile_sub_source.$(OBJEXT) listview_curses.$(OBJEXT) \
textview_curses.$(OBJEXT) view_curses.$(OBJEXT) \
test_top_status.$(OBJEXT)
test_top_status_OBJECTS = $(am_test_top_status_OBJECTS)
test_top_status_DEPENDENCIES = $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
SOURCES = $(drive_grep_proc_SOURCES) $(drive_line_buffer_SOURCES) \
$(drive_listview_SOURCES) $(drive_logfile_SOURCES) \
$(drive_readline_curses_SOURCES) $(drive_vt52_curses_SOURCES) \
$(scripty_SOURCES) $(slicer_SOURCES) $(test_auto_fd_SOURCES) \
$(test_auto_mem_SOURCES) $(test_bookmarks_SOURCES) \
$(test_grep_proc2_SOURCES) $(test_line_buffer2_SOURCES) \
$(test_top_status_SOURCES)
DIST_SOURCES = $(drive_grep_proc_SOURCES) $(drive_line_buffer_SOURCES) \
$(drive_listview_SOURCES) $(drive_logfile_SOURCES) \
$(drive_readline_curses_SOURCES) $(drive_vt52_curses_SOURCES) \
$(scripty_SOURCES) $(slicer_SOURCES) $(test_auto_fd_SOURCES) \
$(test_auto_mem_SOURCES) $(test_bookmarks_SOURCES) \
$(test_grep_proc2_SOURCES) $(test_line_buffer2_SOURCES) \
$(test_top_status_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CFLAGS_PG = @CFLAGS_PG@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CURSES_LIB = @CURSES_LIB@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
OBJCOPY = @OBJCOPY@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PCRE_CFLAGS = @PCRE_CFLAGS@
PCRE_LIBS = @PCRE_LIBS@
RANLIB = @RANLIB@
READLINE_CFLAGS = @READLINE_CFLAGS@
READLINE_LIBS = @READLINE_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SOCI_CXXFLAGS = @SOCI_CXXFLAGS@
SOCI_LIBS = @SOCI_LIBS@
SQLITE3_CFLAGS = @SQLITE3_CFLAGS@
SQLITE3_LDFLAGS = @SQLITE3_LDFLAGS@
SQLITE3_LIBS = @SQLITE3_LIBS@
SQLITE3_VERSION = @SQLITE3_VERSION@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
abssrcdir = @abssrcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
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@
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@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
TESTS_ENVIRONMENT = $(SHELL) $(top_builddir)/TESTS_ENVIRONMENT
AM_CPPFLAGS = \
-I$(top_srcdir)/src \
$(SQLITE3_CFLAGS) \
$(SOCI_CXXFLAGS)
@HAVE_SOCI_FALSE@SOCI_TESTS =
# AM_CFLAGS = -fprofile-arcs -ftest-coverage
# AM_CXXFLAGS = -fprofile-arcs -ftest-coverage
@HAVE_SOCI_TRUE@SOCI_TESTS =
AM_LDFLAGS = \
$(SQLITE3_LDFLAGS)
LDADD = -lz
test_auto_fd_SOURCES = test_auto_fd.cc
test_auto_mem_SOURCES = test_auto_mem.cc
test_bookmarks_SOURCES = test_bookmarks.cc ../src/bookmarks.cc
test_grep_proc2_SOURCES = \
../src/line_buffer.cc \
../src/grep_proc.cc \
test_grep_proc2.cc
test_grep_proc2_LDADD = $(PCRE_LIBS) -lz
test_line_buffer2_SOURCES = \
../src/line_buffer.cc \
test_line_buffer2.cc
test_top_status_SOURCES = \
../src/bookmarks.cc \
../src/logfile.cc \
../src/line_buffer.cc \
../src/log_format.cc \
../src/logfile_sub_source.cc \
../src/listview_curses.cc \
../src/textview_curses.cc \
../src/view_curses.cc \
test_top_status.cc
test_top_status_LDADD = $(CURSES_LIB) -lz
drive_line_buffer_SOURCES = \
../src/line_buffer.cc \
drive_line_buffer.cc
drive_line_buffer_LDADD = $(CURSES_LIB) -lz
drive_grep_proc_SOURCES = \
../src/line_buffer.cc \
../src/grep_proc.cc \
drive_grep_proc.cc
drive_grep_proc_LDADD = $(PCRE_LIBS) -lz
drive_listview_SOURCES = \
../src/listview_curses.cc \
../src/view_curses.cc \
drive_listview.cc
drive_listview_LDADD = $(CURSES_LIB) -lz
drive_logfile_SOURCES = \
../src/logfile.cc \
../src/log_format.cc \
../src/line_buffer.cc \
drive_logfile.cc
drive_vt52_curses_SOURCES = \
../src/vt52_curses.cc \
drive_vt52_curses.cc
drive_vt52_curses_LDADD = $(CURSES_LIB)
drive_readline_curses_SOURCES = \
../src/vt52_curses.cc \
../src/readline_curses.cc \
drive_readline_curses.cc
drive_readline_curses_LDADD = $(CURSES_LIB) $(READLINE_LIBS)
slicer_SOURCES = \
../src/line_buffer.cc \
slicer.cc
scripty_SOURCES = scripty.cc
all: all-am
.SUFFIXES:
.SUFFIXES: .cc .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign test/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign test/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: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-checkPROGRAMS:
-test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
drive_grep_proc$(EXEEXT): $(drive_grep_proc_OBJECTS) $(drive_grep_proc_DEPENDENCIES)
@rm -f drive_grep_proc$(EXEEXT)
$(CXXLINK) $(drive_grep_proc_OBJECTS) $(drive_grep_proc_LDADD) $(LIBS)
drive_line_buffer$(EXEEXT): $(drive_line_buffer_OBJECTS) $(drive_line_buffer_DEPENDENCIES)
@rm -f drive_line_buffer$(EXEEXT)
$(CXXLINK) $(drive_line_buffer_OBJECTS) $(drive_line_buffer_LDADD) $(LIBS)
drive_listview$(EXEEXT): $(drive_listview_OBJECTS) $(drive_listview_DEPENDENCIES)
@rm -f drive_listview$(EXEEXT)
$(CXXLINK) $(drive_listview_OBJECTS) $(drive_listview_LDADD) $(LIBS)
drive_logfile$(EXEEXT): $(drive_logfile_OBJECTS) $(drive_logfile_DEPENDENCIES)
@rm -f drive_logfile$(EXEEXT)
$(CXXLINK) $(drive_logfile_OBJECTS) $(drive_logfile_LDADD) $(LIBS)
drive_readline_curses$(EXEEXT): $(drive_readline_curses_OBJECTS) $(drive_readline_curses_DEPENDENCIES)
@rm -f drive_readline_curses$(EXEEXT)
$(CXXLINK) $(drive_readline_curses_OBJECTS) $(drive_readline_curses_LDADD) $(LIBS)
drive_vt52_curses$(EXEEXT): $(drive_vt52_curses_OBJECTS) $(drive_vt52_curses_DEPENDENCIES)
@rm -f drive_vt52_curses$(EXEEXT)
$(CXXLINK) $(drive_vt52_curses_OBJECTS) $(drive_vt52_curses_LDADD) $(LIBS)
scripty$(EXEEXT): $(scripty_OBJECTS) $(scripty_DEPENDENCIES)
@rm -f scripty$(EXEEXT)
$(CXXLINK) $(scripty_OBJECTS) $(scripty_LDADD) $(LIBS)
slicer$(EXEEXT): $(slicer_OBJECTS) $(slicer_DEPENDENCIES)
@rm -f slicer$(EXEEXT)
$(CXXLINK) $(slicer_OBJECTS) $(slicer_LDADD) $(LIBS)
test_auto_fd$(EXEEXT): $(test_auto_fd_OBJECTS) $(test_auto_fd_DEPENDENCIES)
@rm -f test_auto_fd$(EXEEXT)
$(CXXLINK) $(test_auto_fd_OBJECTS) $(test_auto_fd_LDADD) $(LIBS)
test_auto_mem$(EXEEXT): $(test_auto_mem_OBJECTS) $(test_auto_mem_DEPENDENCIES)
@rm -f test_auto_mem$(EXEEXT)
$(CXXLINK) $(test_auto_mem_OBJECTS) $(test_auto_mem_LDADD) $(LIBS)
test_bookmarks$(EXEEXT): $(test_bookmarks_OBJECTS) $(test_bookmarks_DEPENDENCIES)
@rm -f test_bookmarks$(EXEEXT)
$(CXXLINK) $(test_bookmarks_OBJECTS) $(test_bookmarks_LDADD) $(LIBS)
test_grep_proc2$(EXEEXT): $(test_grep_proc2_OBJECTS) $(test_grep_proc2_DEPENDENCIES)
@rm -f test_grep_proc2$(EXEEXT)
$(CXXLINK) $(test_grep_proc2_OBJECTS) $(test_grep_proc2_LDADD) $(LIBS)
test_line_buffer2$(EXEEXT): $(test_line_buffer2_OBJECTS) $(test_line_buffer2_DEPENDENCIES)
@rm -f test_line_buffer2$(EXEEXT)
$(CXXLINK) $(test_line_buffer2_OBJECTS) $(test_line_buffer2_LDADD) $(LIBS)
test_top_status$(EXEEXT): $(test_top_status_OBJECTS) $(test_top_status_DEPENDENCIES)
@rm -f test_top_status$(EXEEXT)
$(CXXLINK) $(test_top_status_OBJECTS) $(test_top_status_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bookmarks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_grep_proc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_line_buffer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_listview.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_logfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_readline_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_vt52_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grep_proc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/line_buffer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/listview_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log_format.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile_sub_source.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readline_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scripty.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slicer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auto_fd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auto_mem.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_bookmarks.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_grep_proc2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_line_buffer2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_top_status.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textview_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/view_curses.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vt52_curses.Po@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cc.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
line_buffer.o: ../src/line_buffer.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT line_buffer.o -MD -MP -MF $(DEPDIR)/line_buffer.Tpo -c -o line_buffer.o `test -f '../src/line_buffer.cc' || echo '$(srcdir)/'`../src/line_buffer.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/line_buffer.Tpo $(DEPDIR)/line_buffer.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/line_buffer.cc' object='line_buffer.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o line_buffer.o `test -f '../src/line_buffer.cc' || echo '$(srcdir)/'`../src/line_buffer.cc
line_buffer.obj: ../src/line_buffer.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT line_buffer.obj -MD -MP -MF $(DEPDIR)/line_buffer.Tpo -c -o line_buffer.obj `if test -f '../src/line_buffer.cc'; then $(CYGPATH_W) '../src/line_buffer.cc'; else $(CYGPATH_W) '$(srcdir)/../src/line_buffer.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/line_buffer.Tpo $(DEPDIR)/line_buffer.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/line_buffer.cc' object='line_buffer.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o line_buffer.obj `if test -f '../src/line_buffer.cc'; then $(CYGPATH_W) '../src/line_buffer.cc'; else $(CYGPATH_W) '$(srcdir)/../src/line_buffer.cc'; fi`
grep_proc.o: ../src/grep_proc.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT grep_proc.o -MD -MP -MF $(DEPDIR)/grep_proc.Tpo -c -o grep_proc.o `test -f '../src/grep_proc.cc' || echo '$(srcdir)/'`../src/grep_proc.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/grep_proc.Tpo $(DEPDIR)/grep_proc.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/grep_proc.cc' object='grep_proc.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o grep_proc.o `test -f '../src/grep_proc.cc' || echo '$(srcdir)/'`../src/grep_proc.cc
grep_proc.obj: ../src/grep_proc.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT grep_proc.obj -MD -MP -MF $(DEPDIR)/grep_proc.Tpo -c -o grep_proc.obj `if test -f '../src/grep_proc.cc'; then $(CYGPATH_W) '../src/grep_proc.cc'; else $(CYGPATH_W) '$(srcdir)/../src/grep_proc.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/grep_proc.Tpo $(DEPDIR)/grep_proc.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/grep_proc.cc' object='grep_proc.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o grep_proc.obj `if test -f '../src/grep_proc.cc'; then $(CYGPATH_W) '../src/grep_proc.cc'; else $(CYGPATH_W) '$(srcdir)/../src/grep_proc.cc'; fi`
listview_curses.o: ../src/listview_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT listview_curses.o -MD -MP -MF $(DEPDIR)/listview_curses.Tpo -c -o listview_curses.o `test -f '../src/listview_curses.cc' || echo '$(srcdir)/'`../src/listview_curses.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/listview_curses.Tpo $(DEPDIR)/listview_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/listview_curses.cc' object='listview_curses.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o listview_curses.o `test -f '../src/listview_curses.cc' || echo '$(srcdir)/'`../src/listview_curses.cc
listview_curses.obj: ../src/listview_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT listview_curses.obj -MD -MP -MF $(DEPDIR)/listview_curses.Tpo -c -o listview_curses.obj `if test -f '../src/listview_curses.cc'; then $(CYGPATH_W) '../src/listview_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/listview_curses.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/listview_curses.Tpo $(DEPDIR)/listview_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/listview_curses.cc' object='listview_curses.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o listview_curses.obj `if test -f '../src/listview_curses.cc'; then $(CYGPATH_W) '../src/listview_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/listview_curses.cc'; fi`
view_curses.o: ../src/view_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT view_curses.o -MD -MP -MF $(DEPDIR)/view_curses.Tpo -c -o view_curses.o `test -f '../src/view_curses.cc' || echo '$(srcdir)/'`../src/view_curses.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/view_curses.Tpo $(DEPDIR)/view_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/view_curses.cc' object='view_curses.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o view_curses.o `test -f '../src/view_curses.cc' || echo '$(srcdir)/'`../src/view_curses.cc
view_curses.obj: ../src/view_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT view_curses.obj -MD -MP -MF $(DEPDIR)/view_curses.Tpo -c -o view_curses.obj `if test -f '../src/view_curses.cc'; then $(CYGPATH_W) '../src/view_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/view_curses.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/view_curses.Tpo $(DEPDIR)/view_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/view_curses.cc' object='view_curses.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o view_curses.obj `if test -f '../src/view_curses.cc'; then $(CYGPATH_W) '../src/view_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/view_curses.cc'; fi`
logfile.o: ../src/logfile.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT logfile.o -MD -MP -MF $(DEPDIR)/logfile.Tpo -c -o logfile.o `test -f '../src/logfile.cc' || echo '$(srcdir)/'`../src/logfile.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/logfile.Tpo $(DEPDIR)/logfile.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/logfile.cc' object='logfile.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logfile.o `test -f '../src/logfile.cc' || echo '$(srcdir)/'`../src/logfile.cc
logfile.obj: ../src/logfile.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT logfile.obj -MD -MP -MF $(DEPDIR)/logfile.Tpo -c -o logfile.obj `if test -f '../src/logfile.cc'; then $(CYGPATH_W) '../src/logfile.cc'; else $(CYGPATH_W) '$(srcdir)/../src/logfile.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/logfile.Tpo $(DEPDIR)/logfile.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/logfile.cc' object='logfile.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logfile.obj `if test -f '../src/logfile.cc'; then $(CYGPATH_W) '../src/logfile.cc'; else $(CYGPATH_W) '$(srcdir)/../src/logfile.cc'; fi`
log_format.o: ../src/log_format.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT log_format.o -MD -MP -MF $(DEPDIR)/log_format.Tpo -c -o log_format.o `test -f '../src/log_format.cc' || echo '$(srcdir)/'`../src/log_format.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/log_format.Tpo $(DEPDIR)/log_format.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/log_format.cc' object='log_format.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o log_format.o `test -f '../src/log_format.cc' || echo '$(srcdir)/'`../src/log_format.cc
log_format.obj: ../src/log_format.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT log_format.obj -MD -MP -MF $(DEPDIR)/log_format.Tpo -c -o log_format.obj `if test -f '../src/log_format.cc'; then $(CYGPATH_W) '../src/log_format.cc'; else $(CYGPATH_W) '$(srcdir)/../src/log_format.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/log_format.Tpo $(DEPDIR)/log_format.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/log_format.cc' object='log_format.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o log_format.obj `if test -f '../src/log_format.cc'; then $(CYGPATH_W) '../src/log_format.cc'; else $(CYGPATH_W) '$(srcdir)/../src/log_format.cc'; fi`
vt52_curses.o: ../src/vt52_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vt52_curses.o -MD -MP -MF $(DEPDIR)/vt52_curses.Tpo -c -o vt52_curses.o `test -f '../src/vt52_curses.cc' || echo '$(srcdir)/'`../src/vt52_curses.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/vt52_curses.Tpo $(DEPDIR)/vt52_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/vt52_curses.cc' object='vt52_curses.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vt52_curses.o `test -f '../src/vt52_curses.cc' || echo '$(srcdir)/'`../src/vt52_curses.cc
vt52_curses.obj: ../src/vt52_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT vt52_curses.obj -MD -MP -MF $(DEPDIR)/vt52_curses.Tpo -c -o vt52_curses.obj `if test -f '../src/vt52_curses.cc'; then $(CYGPATH_W) '../src/vt52_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/vt52_curses.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/vt52_curses.Tpo $(DEPDIR)/vt52_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/vt52_curses.cc' object='vt52_curses.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o vt52_curses.obj `if test -f '../src/vt52_curses.cc'; then $(CYGPATH_W) '../src/vt52_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/vt52_curses.cc'; fi`
readline_curses.o: ../src/readline_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT readline_curses.o -MD -MP -MF $(DEPDIR)/readline_curses.Tpo -c -o readline_curses.o `test -f '../src/readline_curses.cc' || echo '$(srcdir)/'`../src/readline_curses.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/readline_curses.Tpo $(DEPDIR)/readline_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/readline_curses.cc' object='readline_curses.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o readline_curses.o `test -f '../src/readline_curses.cc' || echo '$(srcdir)/'`../src/readline_curses.cc
readline_curses.obj: ../src/readline_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT readline_curses.obj -MD -MP -MF $(DEPDIR)/readline_curses.Tpo -c -o readline_curses.obj `if test -f '../src/readline_curses.cc'; then $(CYGPATH_W) '../src/readline_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/readline_curses.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/readline_curses.Tpo $(DEPDIR)/readline_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/readline_curses.cc' object='readline_curses.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o readline_curses.obj `if test -f '../src/readline_curses.cc'; then $(CYGPATH_W) '../src/readline_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/readline_curses.cc'; fi`
bookmarks.o: ../src/bookmarks.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bookmarks.o -MD -MP -MF $(DEPDIR)/bookmarks.Tpo -c -o bookmarks.o `test -f '../src/bookmarks.cc' || echo '$(srcdir)/'`../src/bookmarks.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/bookmarks.Tpo $(DEPDIR)/bookmarks.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/bookmarks.cc' object='bookmarks.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bookmarks.o `test -f '../src/bookmarks.cc' || echo '$(srcdir)/'`../src/bookmarks.cc
bookmarks.obj: ../src/bookmarks.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT bookmarks.obj -MD -MP -MF $(DEPDIR)/bookmarks.Tpo -c -o bookmarks.obj `if test -f '../src/bookmarks.cc'; then $(CYGPATH_W) '../src/bookmarks.cc'; else $(CYGPATH_W) '$(srcdir)/../src/bookmarks.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/bookmarks.Tpo $(DEPDIR)/bookmarks.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/bookmarks.cc' object='bookmarks.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o bookmarks.obj `if test -f '../src/bookmarks.cc'; then $(CYGPATH_W) '../src/bookmarks.cc'; else $(CYGPATH_W) '$(srcdir)/../src/bookmarks.cc'; fi`
logfile_sub_source.o: ../src/logfile_sub_source.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT logfile_sub_source.o -MD -MP -MF $(DEPDIR)/logfile_sub_source.Tpo -c -o logfile_sub_source.o `test -f '../src/logfile_sub_source.cc' || echo '$(srcdir)/'`../src/logfile_sub_source.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/logfile_sub_source.Tpo $(DEPDIR)/logfile_sub_source.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/logfile_sub_source.cc' object='logfile_sub_source.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logfile_sub_source.o `test -f '../src/logfile_sub_source.cc' || echo '$(srcdir)/'`../src/logfile_sub_source.cc
logfile_sub_source.obj: ../src/logfile_sub_source.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT logfile_sub_source.obj -MD -MP -MF $(DEPDIR)/logfile_sub_source.Tpo -c -o logfile_sub_source.obj `if test -f '../src/logfile_sub_source.cc'; then $(CYGPATH_W) '../src/logfile_sub_source.cc'; else $(CYGPATH_W) '$(srcdir)/../src/logfile_sub_source.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/logfile_sub_source.Tpo $(DEPDIR)/logfile_sub_source.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/logfile_sub_source.cc' object='logfile_sub_source.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logfile_sub_source.obj `if test -f '../src/logfile_sub_source.cc'; then $(CYGPATH_W) '../src/logfile_sub_source.cc'; else $(CYGPATH_W) '$(srcdir)/../src/logfile_sub_source.cc'; fi`
textview_curses.o: ../src/textview_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT textview_curses.o -MD -MP -MF $(DEPDIR)/textview_curses.Tpo -c -o textview_curses.o `test -f '../src/textview_curses.cc' || echo '$(srcdir)/'`../src/textview_curses.cc
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/textview_curses.Tpo $(DEPDIR)/textview_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/textview_curses.cc' object='textview_curses.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o textview_curses.o `test -f '../src/textview_curses.cc' || echo '$(srcdir)/'`../src/textview_curses.cc
textview_curses.obj: ../src/textview_curses.cc
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT textview_curses.obj -MD -MP -MF $(DEPDIR)/textview_curses.Tpo -c -o textview_curses.obj `if test -f '../src/textview_curses.cc'; then $(CYGPATH_W) '../src/textview_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/textview_curses.cc'; fi`
@am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/textview_curses.Tpo $(DEPDIR)/textview_curses.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../src/textview_curses.cc' object='textview_curses.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o textview_curses.obj `if test -f '../src/textview_curses.cc'; then $(CYGPATH_W) '../src/textview_curses.cc'; else $(CYGPATH_W) '$(srcdir)/../src/textview_curses.cc'; fi`
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; nonemtpy = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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; }; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
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)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
check-TESTS: $(TESTS)
@failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
srcdir=$(srcdir); export srcdir; \
list=' $(TESTS) '; \
if test -n "$$list"; then \
for tst in $$list; do \
if test -f ./$$tst; then dir=./; \
elif test -f $$tst; then dir=; \
else dir="$(srcdir)/"; fi; \
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*$$ws$$tst$$ws*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
echo "XPASS: $$tst"; \
;; \
*) \
echo "PASS: $$tst"; \
;; \
esac; \
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
*$$ws$$tst$$ws*) \
xfail=`expr $$xfail + 1`; \
echo "XFAIL: $$tst"; \
;; \
*) \
failed=`expr $$failed + 1`; \
echo "FAIL: $$tst"; \
;; \
esac; \
else \
skip=`expr $$skip + 1`; \
echo "SKIP: $$tst"; \
fi; \
done; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
banner="All $$all tests passed"; \
else \
banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
banner="$$failed of $$all tests failed"; \
else \
banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
fi; \
fi; \
dashes="$$banner"; \
skipped=""; \
if test "$$skip" -ne 0; then \
skipped="($$skip tests were not run)"; \
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$skipped"; \
fi; \
report=""; \
if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
report="Please report to $(PACKAGE_BUGREPORT)"; \
test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$report"; \
fi; \
dashes=`echo "$$dashes" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
test -z "$$skipped" || echo "$$skipped"; \
test -z "$$report" || echo "$$report"; \
echo "$$dashes"; \
test "$$failed" -eq 0; \
else :; fi
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 $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
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)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-checkPROGRAMS clean-generic 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
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
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
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
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-TESTS check-am clean \
clean-checkPROGRAMS clean-generic ctags distclean \
distclean-compile distclean-generic 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 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:

@ -0,0 +1,33 @@
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include "auto_fd.hh"
void foo(int *fd)
{
*fd = 2;
}
int main(int argc, char *argv[])
{
{
auto_fd fd(open("/dev/null", O_WRONLY));
auto_fd fd2;
printf("1 fd %d\n", fd.get());
fd = -1;
printf("2 fd %d\n", fd.get());
fd = open("/dev/null", O_WRONLY);
fd2 = fd;
printf("3 fd %d\n", fd.get());
printf("4 fd2 %d\n", fd2.get());
foo(fd2.out());
printf("5 fd2 %d\n", fd2.get());
}
printf("nfd %d\n", open("/dev/null", O_WRONLY));
}

@ -0,0 +1,128 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "grep_proc.hh"
#include "line_buffer.hh"
using namespace std;
class my_source : public grep_proc_source {
public:
my_source(auto_fd &fd) : ms_offset(0) {
this->ms_buffer.set_fd(fd);
};
bool grep_value_for_line(int line_number, string &value_out) {
bool retval = false;
try {
size_t len;
char *line;
if ((line = this->ms_buffer.read_line(this->ms_offset,
len)) != NULL) {
value_out = string(line, len);
retval = true;
}
}
catch (line_buffer::error &e) {
fprintf(stderr,
"error: source buffer error %d %s\n",
this->ms_buffer.get_fd(),
strerror(e.e_err));
}
return retval;
};
private:
line_buffer ms_buffer;
off_t ms_offset;
};
class my_sink : public grep_proc_sink {
public:
my_sink() : ms_finished(false) { };
void grep_match(grep_proc &gp,
grep_line_t line,
int start,
int end) {
printf("%d:%d:%d\n", (int)line, start, end);
};
void grep_capture(grep_proc &gp,
grep_line_t line,
int start,
int end,
char *capture) {
fprintf(stderr, "%d(%d:%d)%s\n", (int)line, start, end, capture);
};
void grep_end(grep_proc &gp) {
this->ms_finished = true;
};
bool ms_finished;
};
int main(int argc, char *argv[])
{
int retval = EXIT_SUCCESS;
const char *errptr;
auto_fd fd;
pcre *code;
int eoff;
if (argc < 3) {
fprintf(stderr, "error: expecting pattern and file arguments\n");
retval = EXIT_FAILURE;
}
else if ((fd = open(argv[2], O_RDONLY)) == -1) {
perror("open");
retval = EXIT_FAILURE;
}
else if ((code = pcre_compile(argv[1],
PCRE_CASELESS,
&errptr,
&eoff,
NULL)) == NULL) {
fprintf(stderr, "error: invalid pattern -- %s\n", errptr);
}
else {
my_source ms(fd);
fd_set read_fds;
my_sink msink;
int maxfd;
FD_ZERO(&read_fds);
grep_proc gp(code, ms, maxfd, read_fds);
gp.queue_request();
gp.start();
gp.set_sink(&msink);
while (!msink.ms_finished) {
fd_set rfds = read_fds;
select(maxfd + 1, &rfds, NULL, NULL, NULL);
gp.check_fd_set(rfds);
}
}
return retval;
}

@ -0,0 +1,156 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string>
#include <vector>
#include <algorithm>
#include "lnav_util.hh"
#include "auto_fd.hh"
#include "line_buffer.hh"
using namespace std;
int main(int argc, char *argv[])
{
int c, rnd_iters = 5, retval = EXIT_SUCCESS;
vector<pair<int, int> > index;
auto_fd fd = STDIN_FILENO;
char delim = '\n';
off_t offset = 0;
struct stat st;
while ((c = getopt(argc, argv, "o:d:i:n:")) != -1) {
switch (c) {
case 'o':
if (sscanf(optarg, FORMAT_OFF_T, &offset) != 1) {
fprintf(stderr,
"error: offset is not an integer -- %s\n",
optarg);
retval = EXIT_FAILURE;
}
break;
case 'n':
if (sscanf(optarg, "%d", &rnd_iters) != 1) {
fprintf(stderr,
"error: offset is not an integer -- %s\n",
optarg);
retval = EXIT_FAILURE;
}
break;
case 'i':
{
FILE *file;
if ((file = fopen(optarg, "r")) == NULL) {
perror("open");
retval = EXIT_FAILURE;
}
else {
int line_number = 1, line_offset;
while (fscanf(file, "%d", &line_offset) == 1) {
index.push_back(
make_pair(line_number, line_offset));
line_number += 1;
}
fclose(file);
file = NULL;
}
}
break;
case 'd':
delim = optarg[0];
break;
default:
retval = EXIT_FAILURE;
break;
}
}
argc -= optind;
argv += optind;
if (retval != EXIT_SUCCESS) {
}
else if ((argc == 0) && (index.size() > 0)) {
fprintf(stderr, "error: cannot randomize stdin\n");
retval = EXIT_FAILURE;
}
else if ((argc > 0) && (fd = open(argv[0], O_RDONLY)) == -1) {
perror("open");
retval = EXIT_FAILURE;
}
else if ((argc > 0) && (fstat(fd, &st) == -1)) {
perror("fstat");
retval = EXIT_FAILURE;
}
else {
try {
off_t last_offset = offset;
line_buffer lb;
char *maddr;
char *line;
size_t len;
lb.set_fd(fd);
if (index.size() == 0) {
while ((line = lb.read_line(offset, len, delim)) != NULL) {
line[len] = '\0';
printf("%s", line);
if ((last_offset + len) < offset)
printf("%c", delim);
last_offset = offset;
}
}
else if ((maddr = (char *)mmap(NULL,
st.st_size,
PROT_READ,
MAP_FILE | MAP_PRIVATE,
lb.get_fd(),
0)) == MAP_FAILED) {
perror("mmap");
retval = EXIT_FAILURE;
}
else {
do {
int lpc;
random_shuffle(index.begin(), index.end());
for (lpc = 0; lpc < index.size(); lpc++) {
string line_str;
offset = index[lpc].second;
line = lb.read_line(offset, len, delim);
assert(offset >= 0);
assert(offset <= st.st_size);
assert(memcmp(line,
&maddr[index[lpc].second],
len) == 0);
}
rnd_iters -= 1;
} while (rnd_iters);
printf("All done\n");
}
}
catch (line_buffer::error &e) {
fprintf(stderr, "error: %s\n", strerror(e.e_err));
retval = EXIT_FAILURE;
}
}
return retval;
}

@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "listview_curses.hh"
using namespace std;
static listview_curses lv;
class my_source : public list_data_source {
public:
my_source() : ms_rows(2) { };
size_t listview_rows(const listview_curses &lv) {
return this->ms_rows;
};
void listview_value_for_row(const listview_curses &lv,
vis_line_t row,
attr_line_t &value_out) {
if (row == 0) {
value_out = "Hello";
}
else if (row == 1) {
value_out = "World!";
}
else if (row < this->ms_rows) {
char buffer[32];
snprintf(buffer, sizeof(buffer), "%d", (int)row);
value_out = string(buffer);
}
else {
assert(0);
}
};
bool attrline_next_token(const view_curses &vc,
int line,
struct line_range &lr,
int &attrs_out) {
return false;
};
int ms_rows;
};
int main(int argc, char *argv[])
{
int c, retval = EXIT_SUCCESS;
bool wait_for_input = false;
my_source ms;
WINDOW *win;
win = initscr();
lv.set_data_source(&ms);
lv.set_window(win);
noecho();
while ((c = getopt(argc, argv, "y:t:l:r:h:w")) != -1) {
switch (c) {
case 'y':
lv.set_y(atoi(optarg));
break;
case 'h':
lv.set_height(vis_line_t(atoi(optarg)));
break;
case 't':
lv.set_top(vis_line_t(atoi(optarg)));
break;
case 'l':
lv.set_left(atoi(optarg));
break;
case 'w':
wait_for_input = true;
break;
case 'r':
ms.ms_rows = atoi(optarg);
break;
}
}
lv.do_update();
refresh();
if (wait_for_input)
getch();
endwin();
return retval;
}

@ -0,0 +1,113 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include "logfile.hh"
using namespace std;
typedef enum {
MODE_NONE,
MODE_ECHO,
MODE_LINE_COUNT,
MODE_TIMES,
MODE_LEVELS,
} dl_mode_t;
time_t time(time_t *_unused)
{
return 1194107018;
}
int main(int argc, char *argv[])
{
int c, retval = EXIT_SUCCESS;
dl_mode_t mode = MODE_NONE;
string expected_format;
while ((c = getopt(argc, argv, "ef:ltv")) != -1) {
switch (c) {
case 'f':
expected_format = optarg;
break;
case 'e':
mode = MODE_ECHO;
break;
case 'l':
mode = MODE_LINE_COUNT;
break;
case 't':
mode = MODE_TIMES;
break;
case 'v':
mode = MODE_LEVELS;
break;
}
}
argc -= optind;
argv += optind;
if (retval == EXIT_FAILURE) {
}
else if (argc == 0) {
fprintf(stderr, "error: expecting log file name\n");
}
else {
logfile lf(argv[0]);
struct stat st;
stat(argv[0], &st);
assert(strcmp(argv[0], lf.get_filename().c_str()) == 0);
lf.rebuild_index();
if (expected_format == "") {
assert(lf.get_format() == NULL);
}
else {
// printf("%s %s\n", lf.get_format()->get_name().c_str(), expected_format.c_str());
assert(lf.get_format()->get_name() == expected_format);
}
assert(lf.get_modified_time() == st.st_mtime);
switch (mode) {
case MODE_NONE:
break;
case MODE_ECHO:
for (logfile::iterator iter = lf.begin(); iter != lf.end(); iter++) {
printf("%s\n", lf.read_line(iter).c_str());
}
break;
case MODE_LINE_COUNT:
printf("%d\n", lf.size());
break;
case MODE_TIMES:
for (logfile::iterator iter = lf.begin(); iter != lf.end(); iter++) {
char buffer[1024];
time_t lt;
lt = iter->get_time();
strftime(buffer, sizeof(buffer),
"%b %d %H:%M:%S %Y",
gmtime(&lt));
printf("%s -- %03d\n", buffer, iter->get_millis());
}
break;
case MODE_LEVELS:
for (logfile::iterator iter = lf.begin(); iter != lf.end(); iter++) {
printf("0x%02x\n", iter->get_level());
}
break;
}
}
return retval;
}

@ -0,0 +1,118 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <algorithm>
#include "readline_curses.hh"
using namespace std;
static readline_context::command_map_t COMMANDS;
static struct {
bool dd_active;
readline_curses *dd_rl_view;
volatile sig_atomic_t dd_looping;
} drive_data;
static void rl_callback(void *dummy, readline_curses *rc)
{
string line = rc->get_value();
if (line == "quit")
drive_data.dd_looping = false;
fprintf(stderr, "callback\n");
drive_data.dd_active = false;
}
static void rl_timeout(void *dummy, readline_curses *rc)
{
fprintf(stderr, "timeout\n");
}
int main(int argc, char *argv[])
{
int lpc, c, fd, maxfd, retval = EXIT_SUCCESS;
fd = open("/tmp/lnav.err", O_WRONLY|O_CREAT|O_APPEND, 0666);
dup2(fd, STDERR_FILENO);
close(fd);
fprintf(stderr, "startup\n");
while ((c = getopt(argc, argv, "h")) != -1) {
switch (c) {
case 'h':
break;
default:
break;
}
}
readline_context context(&COMMANDS);
readline_curses rlc;
bool done = false;
fd_set rfds;
rlc.add_context(1, context);
rlc.start();
drive_data.dd_rl_view = &rlc;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
screen_curses sc;
keypad(stdscr, TRUE);
nonl();
cbreak();
noecho();
nodelay(sc.get_window(), 1);
rlc.set_window(sc.get_window());
rlc.set_y(-1);
rlc.set_perform_action(readline_curses::action(rl_callback));
rlc.set_timeout_action(readline_curses::action(rl_timeout));
maxfd = max(STDIN_FILENO, rlc.update_fd_set(rfds));
drive_data.dd_looping = true;
while (drive_data.dd_looping) {
fd_set ready_rfds = rfds;
int rc;
rlc.do_update();
refresh();
rc = select(maxfd + 1, &ready_rfds, NULL, NULL, NULL);
if (rc > 0) {
if (FD_ISSET(STDIN_FILENO, &ready_rfds)) {
int ch;
while ((ch = getch()) != ERR) {
switch (ch) {
case CEOF:
case KEY_RESIZE:
break;
default:
if (drive_data.dd_active) {
rlc.handle_key(ch);
}
else if (ch == ':') {
rlc.focus(1, ":");
drive_data.dd_active = true;
}
break;
}
}
}
rlc.check_fd_set(ready_rfds);
}
}
return retval;
}

@ -0,0 +1,76 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include "view_curses.hh"
#include "vt52_curses.hh"
int main(int argc, char *argv[])
{
int lpc, c, fd, retval = EXIT_SUCCESS;
vt52_curses vt;
fd = open("/tmp/lnav.err", O_WRONLY|O_CREAT|O_APPEND, 0666);
dup2(fd, STDERR_FILENO);
close(fd);
fprintf(stderr, "startup\n");
while ((c = getopt(argc, argv, "y:")) != -1) {
switch (c) {
case 'y':
vt.set_y(atoi(optarg));
break;
}
}
for (lpc = 0; lpc < 1000; lpc++) {
int len;
assert(vt.map_input(random(), len) != NULL);
assert(len > 0);
}
tgetent(NULL, "vt52");
{
static const char *CANNED_INPUT[] = {
"abc",
"\r",
tgetstr("ce", NULL),
"de",
"\n",
"1\n",
"2\n",
"3\n",
"4\n",
"5\n",
"6\n",
"7\n",
"8\n",
"9\n",
"abc",
"\x2",
"\a",
"ab\bcdef",
0
};
screen_curses sc;
noecho();
vt.set_window(sc.get_window());
for (lpc = 0; CANNED_INPUT[lpc]; lpc++) {
vt.map_output(CANNED_INPUT[lpc], strlen(CANNED_INPUT[lpc]));
vt.do_update();
refresh();
getch();
}
getch();
}
return retval;
}

@ -0,0 +1,79 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "logfile.hh"
#include "grep_proc.hh"
#include "line_buffer.hh"
class my_source : public grep_proc_source {
public:
logfile *ms_lf;
my_source(logfile *lf) : ms_lf(lf) { };
size_t grep_lines(void) {
return this->ms_lf->size();
};
void grep_value_for_line(int line,
std::string &value_out,
int pass) {
value_out = this->ms_lf->read_line(this->ms_lf->begin() + line);
};
};
class my_sink : public grep_proc_sink {
public:
void grep_match(grep_line_t line, int start, int end) {
printf("%d - %d:%d\n", (int)line, start, end);
};
};
int main(int argc, char *argv[])
{
int retval = EXIT_SUCCESS;
auto_fd fd;
fd = open("/tmp/gp.err", O_WRONLY|O_CREAT|O_APPEND, 0666);
dup2(fd, STDERR_FILENO);
fprintf(stderr, "startup\n");
if (argc < 2) {
fprintf(stderr, "error: no file given\n");
}
else {
logfile lf(argv[1]);
lf.rebuild_index();
my_source ms(&lf);
my_sink msink;
grep_proc gp("pnp", ms);
gp.start();
gp.set_sink(&msink);
fd_set read_fds;
int maxfd = gp.update_fd_set(read_fds);
while (1) {
fd_set rfds = read_fds;
select(maxfd + 1, &rfds, NULL, NULL, NULL);
gp.check_fd_set(rfds);
if (!FD_ISSET(maxfd, &read_fds))
break;
}
}
return retval;
}

@ -0,0 +1,38 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include "line_buffer.hh"
int main(int argc, char *argv[])
{
int retval = EXIT_SUCCESS;
auto_fd fd;
fd = open("/tmp/lb.err", O_WRONLY|O_CREAT|O_APPEND, 0666);
dup2(fd, STDERR_FILENO);
fprintf(stderr, "startup\n");
if (argc < 2) {
fprintf(stderr, "error: no file given\n");
}
else if ((fd = open(argv[1], O_RDONLY)) == -1) {
perror("open");
}
else {
const char *line;
line_buffer lb;
size_t len;
lb.set_fd(fd);
while ((line = lb.read_line(len)) != NULL) {
printf("%s\n", line);
}
}
return retval;
}

@ -0,0 +1 @@
)07[?47hHello World!                         [?47l8 [?1l>

@ -0,0 +1 @@
)07[?47hWorld!              [?47l8 [?1l>

@ -0,0 +1 @@
)07[?47hello orld!                         [?47l8 [?1l>

@ -0,0 +1 @@
)07[?47horld!              [?47l8 [?1l>

@ -0,0 +1,13 @@
)07[?47h
Hello World! 2 3 4 5 6 7 8 9 10 11
12
13
14
15
16
17
18
19
20
21
22 [?47l8 [?1l>

@ -0,0 +1,13 @@
)07[?47h
Hello World! 2 3 4 5 6 7 8 9 10
11
12
13
14
15
16
17
18
19
20
21 [?47l8 [?1l>

@ -0,0 +1,13 @@
)07[?47h
World! 2 3 4 5 6 7 8 9 10 11
12
13
14
15
16
17
18
19
20
21
22 [?47l8 [?1l>

@ -0,0 +1,3 @@
192.168.202.254 - - [20/Jul/2009:22:59:26 +0000] "GET /vmw/cgi/tramp HTTP/1.0" 200 134 "-" "gPXE/0.9.7"
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 3578929 "-" "gPXE/0.9.7"

@ -0,0 +1,4 @@
Nov 3 09:23:38 veridian automount[7998]: lookup(file): lookup for foobar failed
Nov 3 09:23:38 veridian automount[16442]: attempting to mount entry /auto/opt
Nov 3 09:23:38 veridian automount[7999]: lookup(file): lookup for opt failed
Nov 3 09:47:02 veridian sudo: timstack : TTY=pts/6 ; PWD=/auto/wstimstack/rpms/lbuild/test ; USER=root ; COMMAND=/usr/bin/tail /var/log/messages

@ -0,0 +1,4 @@
Dec 3 09:23:38 veridian automount[7998]: lookup(file): lookup for foobar failed
Dec 3 09:23:38 veridian automount[16442]: attempting to mount entry /auto/opt
Dec 3 09:23:38 veridian automount[7999]: lookup(file): lookup for opt failed
Jan 3 09:47:02 veridian sudo: timstack : TTY=pts/6 ; PWD=/auto/wstimstack/rpms/lbuild/test ; USER=root ; COMMAND=/usr/bin/tail /var/log/messages

@ -0,0 +1,4 @@
#+1162490366
./drive_vt52_curses
#+1162490385
exit

@ -0,0 +1,31 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "logfile.hh"
int main(int argc, char *argv[])
{
int retval = EXIT_SUCCESS;
try {
logfile::iterator iter;
logfile lf("test.log");
for (iter = lf.begin(); iter != lf.end(); iter++) {
printf("%qd %d -- %s\n",
iter->get_offset(),
iter->get_time(),
lf.read_line(iter).c_str());
assert(lf.find_after_time(iter->get_time()) != lf.end());
assert(lf.find_after_time(iter->get_time() + 1000000) == lf.end());
}
}
catch (logfile::error &e) {
printf("error: could not open log file -- %s\n", strerror(e.e_err));
}
return retval;
}

@ -0,0 +1,190 @@
#include <stdio.h>
#include <curses.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <util.h>
#include <sys/time.h>
#include <readline/readline.h>
#include "vt52_curses.hh"
static const int KEY_TIMEOUT = 500 * 1000;
static int got_line = 0;
static int got_timeout = 0;
static void sigalrm(int sig)
{
got_timeout = 1;
}
static void line_ready(char *line)
{
fprintf(stderr, "got line: %s\n", line);
add_history(line);
got_line = 1;
}
static void child_readline(void)
{
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
rl_callback_handler_install("/", (void (*)())line_ready);
while (1) {
fd_set ready_rfds = rfds;
int rc;
rc = select(STDIN_FILENO + 1, &ready_rfds, NULL, NULL, NULL);
if (rc < 0) {
switch (errno) {
case EINTR:
break;
}
}
else {
if (FD_ISSET(STDIN_FILENO, &ready_rfds)) {
struct itimerval itv;
itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = KEY_TIMEOUT;
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &itv, NULL);
rl_callback_read_char();
}
}
if (got_timeout) {
fprintf(stderr, "got timeout\n");
got_timeout = 0;
}
if (got_line) {
rl_callback_handler_remove();
got_line = 0;
rl_callback_handler_install("/", (void (*)())line_ready);
}
}
}
static void finish(int sig)
{
endwin();
exit(0);
}
int main(int argc, char *argv[])
{
int fd, retval = EXIT_SUCCESS;
signal(SIGALRM, sigalrm);
fd = open("/tmp/rltest.err", O_WRONLY|O_CREAT|O_APPEND, 0666);
dup2(fd, STDERR_FILENO);
fprintf(stderr, "startup\n");
if (0) {
while(1) {
char *ret = readline("/");
add_history(ret);
}
}
(void) signal(SIGINT, finish); /* arrange interrupts to terminate */
WINDOW *mainwin = initscr(); /* initialize the curses library */
keypad(stdscr, TRUE); /* enable keyboard mapping */
(void) nonl(); /* tell curses not to do NL->CR/NL on output */
(void) cbreak(); /* take input chars one at a time, no wait for \n */
(void) noecho(); /* don't echo input */
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) < 0)
perror("fcntl");
{
int master, slave;
pid_t rl;
if (openpty(&master, &slave, NULL, NULL, NULL) < 0) {
perror("openpty");
}
else if ((rl = fork()) < 0) {
perror("fork");
}
else if (rl == 0) {
close(master);
master = -1;
dup2(slave, STDIN_FILENO);
dup2(slave, STDOUT_FILENO);
setenv("TERM", "vt52", 1);
child_readline();
}
else {
vt52_curses vc(mainwin);
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
FD_SET(master, &rfds);
while (1) {
fd_set ready_rfds = rfds;
int rc;
rc = select(master + 1, &ready_rfds, NULL, NULL, NULL);
if (rc < 0) {
break;
}
else {
char buffer[1024];
if (FD_ISSET(STDIN_FILENO, &ready_rfds)) {
int ch;
if ((ch = getch()) != ERR) {
const char *bch;
int len;
bch = vc.map_input(ch, len);
if (len > 0) {
fprintf(stderr, "stdin: %x\n", ch);
if (write(master, bch, len) < 0)
perror("write");
}
}
}
if (FD_ISSET(master, &ready_rfds)) {
int lpc;
rc = read(master, buffer, sizeof(buffer));
fprintf(stderr, "child: ");
for (lpc = 0; lpc < rc; lpc++) {
fprintf(stderr, "%x ", buffer[lpc]);
}
fprintf(stderr, "\n");
vc.map_output(buffer, rc);
}
}
refresh();
}
}
}
finish(0);
return retval;
}

@ -0,0 +1,592 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <ncurses.h>
#ifdef HAVE_PTY_H
#include <pty.h>
#endif
#ifdef HAVE_UTIL_H
#include <util.h>
#endif
#include <queue>
#include <algorithm>
#include "auto_fd.hh"
using namespace std;
class child_term {
public:
class error : public std::exception {
public:
error(int err) : e_err(err) { };
int e_err;
};
child_term() {
struct winsize ws;
auto_fd slave;
if (isatty(STDIN_FILENO) &&
tcgetattr(STDIN_FILENO, &this->ct_termios) == -1) {
throw error(errno);
}
if (isatty(STDOUT_FILENO) &&
ioctl(STDOUT_FILENO, TIOCGWINSZ, &this->ct_winsize) == -1) {
throw error(errno);
}
ws.ws_col = 80;
ws.ws_row = 24;
if (openpty(this->ct_master.out(),
slave.out(),
NULL,
NULL,
&ws) < 0) {
throw error(errno);
}
if ((this->ct_child = fork()) == -1)
throw error(errno);
if (this->ct_child == 0) {
this->ct_master.reset();
dup2(slave, STDIN_FILENO);
dup2(slave, STDOUT_FILENO);
setenv("TERM", "xterm-color", 1);
}
else {
slave.reset();
}
};
virtual ~child_term() {
(void)this->wait_for_child();
if (isatty(STDIN_FILENO) &&
tcsetattr(STDIN_FILENO, TCSANOW, &this->ct_termios) == -1) {
perror("tcsetattr");
}
if (isatty(STDOUT_FILENO) &&
ioctl(STDOUT_FILENO, TIOCSWINSZ, &this->ct_winsize) == -1) {
perror("ioctl");
}
};
int wait_for_child(void) {
int retval = -1;
if (this->ct_child > 0) {
kill(this->ct_child, SIGTERM);
this->ct_child = -1;
while (wait(&retval) < 0 && (errno == EINTR));
}
return retval;
};
bool is_child() { return this->ct_child == 0; };
pid_t get_child_pid() { return this->ct_child; };
int get_fd() { return this->ct_master; };
protected:
pid_t ct_child;
auto_fd ct_master;
struct termios ct_termios;
struct winsize ct_winsize;
};
static int tty_raw(int fd)
{
struct termios attr[1];
if (tcgetattr(fd, attr) == -1)
return -1;
attr->c_lflag &= ~(ECHO | ICANON | IEXTEN);
attr->c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
attr->c_cflag &= ~(CSIZE | PARENB);
attr->c_cflag |= (CS8);
attr->c_oflag &= ~(OPOST);
attr->c_cc[VMIN] = 1;
attr->c_cc[VTIME] = 0;
return tcsetattr(fd, TCSANOW, attr);
}
typedef enum {
ET_READ,
} expect_type_t;
struct expect {
expect_type_t e_type;
union {
char *b;
} e_arg;
};
typedef enum {
CT_SLEEP,
CT_WRITE,
} command_type_t;
struct command {
command_type_t c_type;
union {
char *b;
} c_arg;
};
static struct {
const char *sd_program_name;
sig_atomic_t sd_looping;
pid_t sd_child_pid;
const char *sd_to_child_name;
FILE *sd_to_child;
const char *sd_from_child_name;
FILE *sd_from_child;
queue<struct command> sd_replay;
queue<struct expect> sd_expected;
} scripty_data;
static void dump_memory(FILE *dst, char *src, int len)
{
int lpc;
for (lpc = 0; lpc < len; lpc++) {
fprintf(dst, "%02x", src[lpc]);
}
}
static char *hex2bits(const char *src)
{
int len, pos = sizeof(int);
char *retval;
len = strlen(src) / 2;
retval = new char[sizeof(int) + len];
*((int *)retval) = len;
while (src[0]) {
int val;
sscanf(src, "%2x", &val);
src += 2;
retval[pos] = (char)val;
pos += 1;
}
return retval;
}
static void sigchld(int sig)
{
scripty_data.sd_looping = false;
}
static void sigpass(int sig)
{
kill(scripty_data.sd_child_pid, sig);
}
static void usage(void)
{
const char *usage_msg =
"usage: %s [-h] [-t to_child] [-f from_child] -- <cmd>\n"
"\n"
"Recorder for TTY I/O from a child process."
"\n"
"Options:\n"
" -h Print this message, then exit.\n"
" -t <file> The file where any input send to the child process\n"
" should be stored.\n"
" -f <file> The file where any output from the child process\n"
" should be stored.\n";
fprintf(stderr, usage_msg, scripty_data.sd_program_name);
}
int main(int argc, char *argv[])
{
int c, fd, retval = EXIT_SUCCESS;
bool passout = true;
FILE *file;
scripty_data.sd_program_name = argv[0];
scripty_data.sd_looping = true;
while ((c = getopt(argc, argv, "ht:f:r:e:n")) != -1) {
switch (c) {
case 'h':
usage();
exit(retval);
break;
case 't':
scripty_data.sd_to_child_name = optarg;
break;
case 'f':
scripty_data.sd_from_child_name = optarg;
break;
case 'e':
if ((file = fopen(optarg, "r")) == NULL) {
fprintf(stderr, "error: cannot open %s\n", optarg);
retval = EXIT_FAILURE;
}
else {
char line[32 * 1024];
while (fgets(line, sizeof(line), file)) {
char *sp;
if (line[0] == '#' || (sp = strchr(line, ' ')) == NULL) {
}
else {
struct expect exp;
*sp = '\0';
sp += 1;
if (strcmp(line, "read") == 0) {
exp.e_type = ET_READ;
exp.e_arg.b = hex2bits(sp);
}
else {
fprintf(stderr,
"error: unknown command -- %s\n",
line);
retval = EXIT_FAILURE;
}
scripty_data.sd_expected.push(exp);
}
}
fclose(file);
file = NULL;
}
break;
case 'r':
if ((file = fopen(optarg, "r")) == NULL) {
fprintf(stderr, "error: cannot open %s\n", optarg);
retval = EXIT_FAILURE;
}
else {
char line[32 * 1024];
while (fgets(line, sizeof(line), file)) {
char *sp;
if (line[0] == '#' || (sp = strchr(line, ' ')) == NULL) {
}
else {
struct command cmd;
*sp = '\0';
sp += 1;
if (strcmp(line, "sleep") == 0) {
cmd.c_type = CT_SLEEP;
}
else if (strcmp(line, "write") == 0) {
cmd.c_type = CT_WRITE;
cmd.c_arg.b = hex2bits(sp);
scripty_data.sd_replay.push(cmd);
}
else {
fprintf(stderr,
"error: unknown command -- %s\n",
line);
retval = EXIT_FAILURE;
}
}
}
fclose(file);
file = NULL;
}
break;
case 'n':
passout = false;
break;
default:
retval = EXIT_FAILURE;
break;
}
}
argc -= optind;
argv += optind;
if ((scripty_data.sd_to_child_name != NULL) &&
(scripty_data.sd_to_child =
fopen(scripty_data.sd_to_child_name, "w")) == NULL) {
fprintf(stderr,
"error: unable to open %s -- %s\n",
scripty_data.sd_to_child_name,
strerror(errno));
retval = EXIT_FAILURE;
}
if (scripty_data.sd_from_child_name != NULL) {
if (strcmp(scripty_data.sd_from_child_name, "-") == 0) {
scripty_data.sd_from_child = stdout;
}
else if ((scripty_data.sd_from_child =
fopen(scripty_data.sd_from_child_name, "w")) == NULL) {
fprintf(stderr,
"error: unable from open %s -- %s\n",
scripty_data.sd_from_child_name,
strerror(errno));
retval = EXIT_FAILURE;
}
}
fd = open("/tmp/scripty.err", O_WRONLY|O_CREAT|O_APPEND, 0666);
dup2(fd, STDERR_FILENO);
close(fd);
fprintf(stderr, "startup\n");
if (scripty_data.sd_to_child != NULL)
fcntl(fileno(scripty_data.sd_to_child), F_SETFD, 1);
if (scripty_data.sd_from_child != NULL)
fcntl(fileno(scripty_data.sd_from_child), F_SETFD, 1);
if (retval != EXIT_FAILURE) {
child_term ct;
if (ct.is_child()) {
execvp(argv[0], argv);
perror("execvp");
exit(-1);
}
else {
int maxfd, out_len = 0, exp_pos = 0, exp_len = 0;
bool got_expected = true;
struct timeval last, now;
char out_buffer[8192];
fd_set read_fds;
char *exp_data = NULL;
scripty_data.sd_child_pid = ct.get_child_pid();
signal(SIGINT, sigpass);
signal(SIGTERM, sigpass);
signal(SIGCHLD, sigchld);
gettimeofday(&now, NULL);
last = now;
FD_ZERO(&read_fds);
FD_SET(STDIN_FILENO, &read_fds);
FD_SET(ct.get_fd(), &read_fds);
fprintf(stderr, "goin in the loop\n");
tty_raw(STDIN_FILENO);
if (!scripty_data.sd_expected.empty()) {
struct expect exp = scripty_data.sd_expected.front();
scripty_data.sd_expected.pop();
switch (exp.e_type) {
case ET_READ:
exp_pos = sizeof(int);
exp_len = *((int *)exp.e_arg.b) + sizeof(int);
exp_data = exp.e_arg.b;
break;
}
got_expected = false;
}
maxfd = max(STDIN_FILENO, ct.get_fd());
while (scripty_data.sd_looping) {
fd_set ready_rfds = read_fds;
struct timeval diff, to;
int rc;
to.tv_sec = 0;
to.tv_usec = 10000;
rc = select(maxfd + 1, &ready_rfds, NULL, NULL, &to);
if (rc == 0) {
if (exp_data != NULL && exp_pos == exp_len && !got_expected) {
exp_data = NULL;
if (!scripty_data.sd_expected.empty()) {
struct expect exp = scripty_data.sd_expected.front();
delete [] exp_data;
scripty_data.sd_expected.pop();
switch (exp.e_type) {
case ET_READ:
exp_pos = sizeof(int);
exp_len = *((int *)exp.e_arg.b) + sizeof(int);
exp_data = exp.e_arg.b;
break;
}
}
got_expected = true;
}
if (!scripty_data.sd_replay.empty() && got_expected) {
struct command cmd = scripty_data.sd_replay.front();
int len;
scripty_data.sd_replay.pop();
fprintf(stderr, "replay %d\n", scripty_data.sd_replay.size());
switch (cmd.c_type) {
case CT_SLEEP:
break;
case CT_WRITE:
len = *((int *)cmd.c_arg.b);
write(ct.get_fd(),
cmd.c_arg.b + sizeof(int),
len);
delete [] cmd.c_arg.b;
break;
}
got_expected = false;
}
}
else if (rc < 0) {
switch (errno) {
case EINTR:
break;
default:
fprintf(stderr, "select %s\n", strerror(errno));
scripty_data.sd_looping = false;
break;
}
}
else {
char buffer[1024];
gettimeofday(&now, NULL);
timersub(&now, &last, &diff);
if (FD_ISSET(STDIN_FILENO, &ready_rfds)) {
rc = read(STDIN_FILENO, buffer, sizeof(buffer));
if (rc < 0) {
scripty_data.sd_looping = false;
}
else if (rc == 0) {
FD_CLR(STDIN_FILENO, &read_fds);
}
else {
write(ct.get_fd(), buffer, rc);
if (scripty_data.sd_to_child != NULL) {
fprintf(scripty_data.sd_to_child,
"sleep %ld.%06d\n"
"write ",
diff.tv_sec, diff.tv_usec);
dump_memory(scripty_data.sd_to_child,
buffer,
rc);
fprintf(scripty_data.sd_to_child, "\n");
}
if (scripty_data.sd_from_child != NULL) {
fprintf(stderr, "do write %d\n", out_len);
fprintf(scripty_data.sd_from_child, "read ");
dump_memory(scripty_data.sd_from_child,
out_buffer,
out_len);
fprintf(scripty_data.sd_from_child, "\n");
fprintf(scripty_data.sd_from_child,
"# write ");
dump_memory(scripty_data.sd_from_child,
buffer,
rc);
fprintf(scripty_data.sd_from_child, "\n");
out_len = 0;
}
}
}
if (FD_ISSET(ct.get_fd(), &ready_rfds)) {
rc = read(ct.get_fd(), buffer, sizeof(buffer));
if (rc <= 0) {
scripty_data.sd_looping = false;
}
else {
if (passout)
write(STDOUT_FILENO, buffer, rc);
if (scripty_data.sd_from_child != NULL) {
fprintf(stderr, "got out %d\n", rc);
memcpy(&out_buffer[out_len],
buffer,
rc);
out_len += rc;
}
if (exp_data != NULL) {
int clen = min((exp_len - exp_pos), rc);
fprintf(stderr, "cmp %d %d %d %d\n", exp_len, exp_pos, rc, clen);
if (memcmp(&exp_data[exp_pos],
buffer,
clen) == 0) {
exp_pos += clen;
fprintf(stderr, "exp %d %d\n", exp_pos, clen);
if (exp_pos == exp_len) {
exp_data = NULL;
if (!scripty_data.sd_expected.empty()) {
struct expect exp = scripty_data.sd_expected.front();
delete [] exp_data;
scripty_data.sd_expected.pop();
switch (exp.e_type) {
case ET_READ:
exp_pos = sizeof(int);
exp_len = *((int *)exp.e_arg.b) + sizeof(int);
exp_data = exp.e_arg.b;
break;
}
}
got_expected = true;
}
}
else {
scripty_data.sd_looping = false;
retval = EXIT_FAILURE;
}
}
}
}
}
last = now;
}
}
if (!scripty_data.sd_expected.empty())
retval = EXIT_FAILURE;
retval = ct.wait_for_child() || retval;
}
if (scripty_data.sd_to_child != NULL) {
fclose(scripty_data.sd_to_child);
scripty_data.sd_to_child = NULL;
}
if (scripty_data.sd_from_child != NULL) {
fclose(scripty_data.sd_from_child);
scripty_data.sd_from_child = NULL;
}
return retval;
}

@ -0,0 +1,19 @@
#include <stdio.h>
#include "strong_int.hh"
class __dsi1_distinct;
typedef strong_int<int, __dsi1_distinct> dsi1_t;
class __dsi2_distinct;
typedef strong_int<int, __dsi2_distinct> dsi2_t;
STRONG_INT_TYPE(int, dsi3);
int main(int argc, char *argv[])
{
dsi1_t dsi1(0);
dsi2_t dsi2(1);
dsi3_t dsi3(2);
printf("%d\n", sizeof(dsi1));
}

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

Loading…
Cancel
Save