mirror of https://github.com/tstack/lnav
first commit
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
|
@ -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)
|
||||
])
|
||||
|
File diff suppressed because it is too large
Load Diff
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(¤t_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(<));
|
||||
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,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 @@
|
||||
Hello, World!
|
@ -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…
Reference in New Issue