mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Merge branch 'master' into topic/seth/ssl-analyzer-work
This commit is contained in:
commit
7ffbac68a4
857 changed files with 3251 additions and 217166 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
build
|
12
.gitmodules
vendored
Normal file
12
.gitmodules
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
[submodule "aux/bro-aux"]
|
||||
path = aux/bro-aux
|
||||
url = git://git.icir.org/bro-aux
|
||||
[submodule "aux/binpac"]
|
||||
path = aux/binpac
|
||||
url = git://git.icir.org/binpac
|
||||
[submodule "aux/broccoli"]
|
||||
path = aux/broccoli
|
||||
url = git://git.icir.org/broccoli
|
||||
[submodule "aux/broctl"]
|
||||
path = aux/broctl
|
||||
url = git://git.icir.org/broctl
|
0
AUTHORS
0
AUTHORS
77
CHANGES
77
CHANGES
|
@ -2,6 +2,83 @@
|
|||
|
||||
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
1.6-dev.4 Sat Jan 15 14:14:21 PST 2011
|
||||
|
||||
- Updates to the build system (Jonathan Siwek)
|
||||
|
||||
* ``make dist`` is now available to be used with the top-level
|
||||
Makefile for creating source packages according to #344.
|
||||
|
||||
* ``make-rpm-packages`` and ``make-mac-packages`` scripts can
|
||||
now generate binary packages according to #295.
|
||||
|
||||
* Additional configure options to change packaging behavior.
|
||||
|
||||
* OS X builds will now prefer to link static libraries of
|
||||
optional dependencies that don't come with the vanilla
|
||||
operating system.
|
||||
|
||||
* Fix for OS X 10.5 compile error dealing with the llabs()
|
||||
function from stdlib.
|
||||
|
||||
* Installing as a different user than the one that
|
||||
configured/built now works (although, a harmless error message
|
||||
about not being able to write the install manifest may occur).
|
||||
|
||||
1.6-dev.3 Wed Dec 8 04:09:38 PST 2010
|
||||
|
||||
- Merge with Subversion repository as of r7137. Incorporated change:
|
||||
|
||||
* Fix for packet processing resumption when a remote Bro dies
|
||||
during state synchronization (Robin Sommer).
|
||||
|
||||
1.6-dev.2 Wed Dec 8 03:57:03 PST 2010
|
||||
|
||||
- Compatibility fix for OpenSSL 1.0.0 (Christian Kreibich, Gregor
|
||||
Maier).
|
||||
|
||||
1.6-dev.1 Sat Nov 27 12:19:47 PST 2010
|
||||
|
||||
- Merge with Subversion repository as of r7098. Incorporated changes:
|
||||
|
||||
* Rotation post-processors are now passed an additional argument
|
||||
indicating whether Bro is terminating (Robin Sommer).
|
||||
|
||||
* Bro now consistently generates a file_opened event for all
|
||||
fopen() calls. (Robin Sommer).
|
||||
|
||||
* You can now redefine the email_notice_to function (Robin
|
||||
Sommer).
|
||||
|
||||
1.6-dev.0 Fri Nov 26 13:48:11 PST 2010
|
||||
|
||||
- The Bro source code is now developed in the new git repositories.
|
||||
See the developer pages at http://www.bro-ids.org for more
|
||||
information on the new development process.
|
||||
|
||||
- Bro's build and installation setup has been moved from GNU
|
||||
autotools to CMake. As a result of that, layout and specifics of
|
||||
the distribution has changed significantly.
|
||||
|
||||
- Lots of pieces have been removed from the distribution that are
|
||||
either now unnecessary or are no longer maintained.
|
||||
|
||||
- As part of the cleanup, a numbef of Bro configure options and
|
||||
their corresponding functionality have been removed, including:
|
||||
|
||||
* --disable-select-loop
|
||||
* --with-dag
|
||||
* --disable-nbdns
|
||||
* --enable-activemapping
|
||||
* --enable-activemapping
|
||||
* --enable-shippedpcap
|
||||
|
||||
- The previous configure option --enable-int64 is now enabled by default,
|
||||
and can no longer be disabled.
|
||||
|
||||
- ClamAV support has been removed, which has been non-functional for
|
||||
a while already.
|
||||
|
||||
1.5.2.7 Sun Sep 12 19:39:49 PDT 2010
|
||||
|
||||
- Addressed a number of lint nits (Vern Paxson).
|
||||
|
|
238
CMakeLists.txt
Normal file
238
CMakeLists.txt
Normal file
|
@ -0,0 +1,238 @@
|
|||
project(Bro)
|
||||
|
||||
########################################################################
|
||||
## CMake Configuration
|
||||
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
|
||||
|
||||
# Prohibit in-source builds.
|
||||
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||
message(FATAL_ERROR "In-source builds are not allowed. Please use "
|
||||
"./configure to choose a build directory and "
|
||||
"initialize the build configuration.")
|
||||
endif ()
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
|
||||
# uninstall target
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(uninstall COMMAND
|
||||
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
|
||||
endif ()
|
||||
|
||||
########################################################################
|
||||
## Project/Build Configuration
|
||||
|
||||
set(BRO_ROOT_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
if (NOT POLICYDIR)
|
||||
# set the default policy installation path (user did not specify one)
|
||||
set(POLICYDIR ${BRO_ROOT_DIR}/share/bro)
|
||||
endif ()
|
||||
|
||||
# sanitize the policy install directory into an absolute path
|
||||
# (CMake is confused by ~ as a representation of home directory)
|
||||
get_filename_component(POLICYDIR ${POLICYDIR} ABSOLUTE)
|
||||
|
||||
configure_file(bro-path-dev.in ${CMAKE_CURRENT_BINARY_DIR}/bro-path-dev)
|
||||
|
||||
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
|
||||
|
||||
set(EXTRA_COMPILE_FLAGS "-Wall -Wno-unused")
|
||||
|
||||
if (ENABLE_DEBUG)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DDEBUG")
|
||||
else ()
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo)
|
||||
endif ()
|
||||
|
||||
# Compiler flags may already exist in CMake cache (e.g. when specifying
|
||||
# CFLAGS environment variable before running cmake for the the first time)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_COMPILE_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}")
|
||||
|
||||
########################################################################
|
||||
## Dependency Configuration
|
||||
|
||||
include(FindRequiredPackage)
|
||||
|
||||
# Check cache value first to avoid displaying "Found sed" messages everytime
|
||||
if (NOT SED_EXE)
|
||||
find_program(SED_EXE sed)
|
||||
if (NOT SED_EXE)
|
||||
message(FATAL_ERROR "Could not find required dependency: sed")
|
||||
else ()
|
||||
message(STATUS "Found sed: ${SED_EXE}")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
FindRequiredPackage(Perl)
|
||||
FindRequiredPackage(FLEX)
|
||||
FindRequiredPackage(BISON)
|
||||
FindRequiredPackage(PCAP)
|
||||
FindRequiredPackage(OpenSSL)
|
||||
FindRequiredPackage(BIND)
|
||||
|
||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/binpac/CMakeLists.txt)
|
||||
add_subdirectory(aux/binpac)
|
||||
endif ()
|
||||
FindRequiredPackage(BinPAC)
|
||||
|
||||
if (MISSING_PREREQS)
|
||||
foreach (prereq ${MISSING_PREREQ_DESCS})
|
||||
message(SEND_ERROR ${prereq})
|
||||
endforeach ()
|
||||
message(FATAL_ERROR "Configuration aborted due to missing prerequisites")
|
||||
endif ()
|
||||
|
||||
include_directories(BEFORE
|
||||
${PCAP_INCLUDE_DIR}
|
||||
${OpenSSL_INCLUDE_DIR}
|
||||
${BIND_INCLUDE_DIR}
|
||||
${BinPAC_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
# Optional Dependencies
|
||||
|
||||
set(HAVE_LIBMAGIC false)
|
||||
find_package(LibMagic)
|
||||
if (LIBMAGIC_FOUND)
|
||||
set(HAVE_LIBMAGIC true)
|
||||
include_directories(BEFORE ${LibMagic_INCLUDE_DIR})
|
||||
list(APPEND OPTLIBS ${LibMagic_LIBRARY})
|
||||
endif ()
|
||||
|
||||
set(HAVE_LIBZ false)
|
||||
find_package(ZLIB)
|
||||
if (ZLIB_FOUND)
|
||||
set(HAVE_LIBZ true)
|
||||
include_directories(BEFORE ${ZLIB_INCLUDE_DIR})
|
||||
list(APPEND OPTLIBS ${ZLIB_LIBRARY})
|
||||
endif ()
|
||||
|
||||
set(USE_GEOIP false)
|
||||
find_package(LibGeoIP)
|
||||
if (LIBGEOIP_FOUND)
|
||||
set(USE_GEOIP true)
|
||||
include_directories(BEFORE ${LibGeoIP_INCLUDE_DIR})
|
||||
list(APPEND OPTLIBS ${LibGeoIP_LIBRARY})
|
||||
endif ()
|
||||
|
||||
set(USE_PERFTOOLS false)
|
||||
if (ENABLE_PERFTOOLS)
|
||||
find_package(GooglePerftools)
|
||||
if (GOOGLEPERFTOOLS_FOUND)
|
||||
set(USE_PERFTOOLS true)
|
||||
include_directories(BEFORE ${GooglePerftools_INCLUDE_DIR})
|
||||
list(APPEND OPTLIBS ${GooglePerftools_LIBRARIES})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
########################################################################
|
||||
## System Introspection
|
||||
|
||||
include(TestBigEndian)
|
||||
test_big_endian(WORDS_BIGENDIAN)
|
||||
|
||||
include(OSSpecific)
|
||||
include(CheckTypes)
|
||||
include(CheckHeaders)
|
||||
include(CheckFunctions)
|
||||
include(MiscTests)
|
||||
include(PCAPTests)
|
||||
include(OpenSSLTests)
|
||||
include(CheckNameserCompat)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
########################################################################
|
||||
## Recurse on sub-directories
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(policy)
|
||||
#add_subdirectory(scripts)
|
||||
#add_subdirectory(doc)
|
||||
|
||||
include(CheckOptionalBuildSources)
|
||||
|
||||
CheckOptionalBuildSources(aux/broctl Broctl INSTALL_BROCTL)
|
||||
CheckOptionalBuildSources(aux/bro-aux Bro-Aux INSTALL_AUX_TOOLS)
|
||||
CheckOptionalBuildSources(aux/broccoli Broccoli INSTALL_BROCCOLI)
|
||||
|
||||
########################################################################
|
||||
## Packaging Setup
|
||||
|
||||
if (INSTALL_BROCTL)
|
||||
# CPack RPM Generator may not automatically detect this
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "python >= 2.4.0")
|
||||
endif ()
|
||||
|
||||
# If this CMake project is a sub-project of another, we will not
|
||||
# configure the generic packaging because CPack will fail in the case
|
||||
# that the parent project has already configured packaging
|
||||
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
|
||||
include(ConfigurePackaging)
|
||||
ConfigurePackaging(${VERSION})
|
||||
endif ()
|
||||
|
||||
########################################################################
|
||||
## Build Summary
|
||||
|
||||
if (CMAKE_BUILD_TYPE)
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} BuildType)
|
||||
endif ()
|
||||
|
||||
if (INSTALL_BROCTL)
|
||||
if (STANDALONE)
|
||||
set(BROCTL_INSTALL_MODE "standalone")
|
||||
else ()
|
||||
set(BROCTL_INSTALL_MODE "cluster")
|
||||
endif ()
|
||||
else ()
|
||||
set(BROCTL_INSTALL_MODE "false")
|
||||
endif ()
|
||||
|
||||
message(
|
||||
"\n====================| Bro Build Summary |====================="
|
||||
"\n"
|
||||
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
|
||||
"\nPolicy dir: ${POLICYDIR}"
|
||||
"\nDebug mode: ${ENABLE_DEBUG}"
|
||||
"\n"
|
||||
"\nCC: ${CMAKE_C_COMPILER}"
|
||||
"\nCFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BuildType}}"
|
||||
"\nCXX: ${CMAKE_CXX_COMPILER}"
|
||||
"\nCXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BuildType}}"
|
||||
"\nCPP: ${CMAKE_CXX_COMPILER}"
|
||||
"\n"
|
||||
"\nBroccoli: ${INSTALL_BROCCOLI}"
|
||||
"\nBroctl: ${BROCTL_INSTALL_MODE}"
|
||||
"\nAux. Tools: ${INSTALL_AUX_TOOLS}"
|
||||
"\n"
|
||||
"\nGeoIP: ${USE_GEOIP}"
|
||||
"\nlibz: ${HAVE_LIBZ}"
|
||||
"\nlibmagic: ${HAVE_LIBMAGIC}"
|
||||
"\nGoogle perftools: ${USE_PERFTOOLS}"
|
||||
"\n"
|
||||
"\n================================================================\n"
|
||||
)
|
||||
|
||||
########################################################################
|
||||
## Show warning when installing user is different from the one that configured
|
||||
|
||||
install(CODE "
|
||||
if (NOT $ENV{USER} STREQUAL \$ENV{USER})
|
||||
message(STATUS \"ATTENTION: Install is being performed by user \"
|
||||
\"'\$ENV{USER}', but the build directory was configured by \"
|
||||
\"user '$ENV{USER}'. This may result in a permissions error \"
|
||||
\"when writing the install manifest, but you can ignore it \"
|
||||
\"and consider the installation as successful if you don't \"
|
||||
\"care about the install manifest.\")
|
||||
endif ()
|
||||
")
|
9
COPYING
9
COPYING
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 1995-2008, The Regents of the University of California,
|
||||
Copyright (c) 1995-2010, The Regents of the University of California,
|
||||
through Lawrence Berkeley National Laboratory. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
Note that some files in the Bro distribution carry their own copyright
|
||||
notices. The above applies to the Bro scripts in policy/ (other than as
|
||||
noted below) and the source files in src/ , other than:
|
||||
noted below) and the source files in src/, other than:
|
||||
|
||||
policy/sigs/p0fsyn.osf
|
||||
src/H3.h
|
||||
|
@ -44,6 +44,5 @@ noted below) and the source files in src/ , other than:
|
|||
src/patricia.c
|
||||
src/patricia.h
|
||||
|
||||
In addition, the build components such as Makefile.in, acinclude.m4, and
|
||||
others have separate copyrights, as do a number of the elements in the
|
||||
aux/ subdirectory and in scripts/s2b/snort_rules2.2/ .
|
||||
In addition, other components, such as the build system, may have
|
||||
separate copyrights.
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
TODO: Needs update. -Robin
|
||||
|
||||
- Make sure BroV6 works.
|
||||
|
||||
- Make sure --enable-int64 builds w/o warnings.
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
README
|
||||
VERSION
|
||||
bro
|
135
INSTALL
135
INSTALL
|
@ -1,104 +1,97 @@
|
|||
==============
|
||||
Installing Bro
|
||||
==============
|
||||
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
Bro relies on the following libraries and tools, which need to be installed
|
||||
before you begin with the installation:
|
||||
before you begin:
|
||||
|
||||
* Libpcap
|
||||
If libpcap is already installed on the system, by default Bro
|
||||
will use that one. Otherwise, it falls back to a version shipped
|
||||
with the Bro distribution.
|
||||
* Libpcap headers and libraries
|
||||
Network traffic capture library
|
||||
|
||||
* Flex
|
||||
Flex is already installed on most systems, so with luck you can
|
||||
skip having to install it yourself.
|
||||
* Flex (Fast Lexical Analyzer)
|
||||
Flex is already installed on most systems, so with luck you can
|
||||
skip having to install it yourself.
|
||||
|
||||
* Bison or byacc
|
||||
These come with many systems, but if you get errors compiling
|
||||
parse.y, you will need to install them. bison is available
|
||||
from GNU sites such as ftp.gnu.org.
|
||||
* Bison (GNU Parser Generator)
|
||||
This comes with many systems, but if you get errors compiling
|
||||
parse.y, you will need to install it.
|
||||
|
||||
* Perl
|
||||
Used only during the Bro build process
|
||||
|
||||
* sed
|
||||
Used only during the Bro build process
|
||||
|
||||
* BIND8 headers and libraries
|
||||
These are usually already installed as well.
|
||||
These are usually already installed as well.
|
||||
|
||||
* Autotools
|
||||
If you have checked the source out from Bro's Subversion
|
||||
repository, you need the autotools suite installed. In this
|
||||
case, run "./autogen.sh" first right after the check out.
|
||||
Otherwise the installation steps below will fail.
|
||||
* OpenSSL headers and libraries
|
||||
For analysis of SSL certificates by the HTTP analyzer, and
|
||||
for encrypted Bro-to-Bro communication. These are likely installed,
|
||||
though some platforms may require installation of a 'devel' package
|
||||
for the headers.
|
||||
|
||||
* CMake 2.8 or greater
|
||||
CMake is a cross-platform, open-source build system, typically
|
||||
not installed by default. See http://www.cmake.org for more
|
||||
information regarding CMake and the installation steps below for
|
||||
how to use it to build this distribution. CMake generates native
|
||||
Makefiles that depend on GNU Make by default.
|
||||
|
||||
Bro can also make uses of some optional libraries if they are found at
|
||||
installation time:
|
||||
|
||||
* OpenSSL
|
||||
For analysis of SSL certificates by the HTTP analyzer, and
|
||||
for encrypted Bro-to-Bro communication.
|
||||
|
||||
* Libmagic
|
||||
For identifying file types (e.g., in FTP transfers).
|
||||
|
||||
For identifying file types (e.g., in FTP transfers).
|
||||
|
||||
* LibGeoIP
|
||||
For geo-locating IP addresses.
|
||||
|
||||
For geo-locating IP addresses.
|
||||
|
||||
* Libz
|
||||
For decompressing HTTP bodies by the HTTP analyzer, and for
|
||||
compressed Bro-to-Bro communication.
|
||||
|
||||
* Endace's DAG tools:
|
||||
For native support of Endace DAG cards.
|
||||
|
||||
For decompressing HTTP bodies by the HTTP analyzer, and for
|
||||
compressed Bro-to-Bro communication.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To build and install into /usr/local:
|
||||
To build and install into /usr/local/bro:
|
||||
|
||||
> ./configure
|
||||
> make
|
||||
> make install
|
||||
> ./configure
|
||||
> cd build
|
||||
> make
|
||||
> make install
|
||||
|
||||
This will install the Bro binary into /usr/local/bin/bro and the policy
|
||||
files into /usr/local/share/bro.
|
||||
This will perform an out-of-source build into a directory called
|
||||
build/, using default build options. It then installs the Bro binary
|
||||
into /usr/local/bro/bin. Depending on the Bro package you
|
||||
downloaded, there may be auxiliary tools and libraries available in
|
||||
the aux/ directory. If so, they will be installed by default as well
|
||||
if not explicitly disabled via configure options and may also have
|
||||
additional installation/configuration instructions that you can
|
||||
find in their source directories.
|
||||
|
||||
As usual you can specify a different installation directory with
|
||||
You can specify a different installation directory with
|
||||
|
||||
> ./configure --prefix=<dir>".
|
||||
> ./configure --prefix=<dir>
|
||||
|
||||
Run "./configure --help" for more options.
|
||||
Note that "/usr" and "/opt/bro" are standard prefixes for binary
|
||||
packages to be installed, so those are typically not good choices
|
||||
unless you are creating such a package.
|
||||
|
||||
Run "./configure --help" for more options.
|
||||
|
||||
Running Bro
|
||||
===========
|
||||
|
||||
Bro is a complex program and it takes a bit of time to get familiar
|
||||
with it. In the following we give a few simple examples. See
|
||||
http://www.bro-ids.org/wiki for more information.
|
||||
with it. In the following we give a few simple examples. See the
|
||||
quickstart guide at http://www.bro-ids.org for more information; you
|
||||
can the source that in doc/quick-start.
|
||||
|
||||
To run a policy file from /usr/local/share/bro, such as mt.bro, on a
|
||||
previously captured tcpdump save file named foo:
|
||||
|
||||
bro -r foo mt.bro
|
||||
|
||||
To run from interface le0:
|
||||
|
||||
bro -i le0 mt
|
||||
|
||||
You can alternatively specify interface and scripts to load in your own
|
||||
policy file:
|
||||
|
||||
@load mt
|
||||
redef interfaces = "le0";
|
||||
|
||||
and then run
|
||||
|
||||
bro ./my-policy.bro
|
||||
|
||||
You can see the BPF filter Bro will use (if not overridden) by executing
|
||||
|
||||
bro mt print-filter
|
||||
|
||||
To run interactively (e.g., for playing with expression evaluation):
|
||||
|
||||
bro
|
||||
|
||||
"bro -h" lists the various options.
|
||||
For developers that wish to run Bro after performing "make", but
|
||||
without performing "make install", see build/bro-path-dev for
|
||||
an example.
|
||||
|
|
71
Makefile
Normal file
71
Makefile
Normal file
|
@ -0,0 +1,71 @@
|
|||
#
|
||||
# A simple static wrapper for a number of standard Makefile targets,
|
||||
# mostly just forwarding to build/Makefile. This is provided only for
|
||||
# convenience and supports only a subset of what CMake's Makefile
|
||||
# to offer. For more, execute that one directly.
|
||||
#
|
||||
|
||||
BUILD=build
|
||||
BROCCOLI=aux/broccoli
|
||||
BROCTL=aux/broctl
|
||||
|
||||
# CMake/CPack versions before 2.8.2 have bugs that can create bad packages
|
||||
CMAKE_PACK_REQ=2.8.2
|
||||
CMAKE_VER=`cmake -version`
|
||||
|
||||
OSX_VER_CMD=sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2
|
||||
|
||||
all: configured
|
||||
( cd $(BUILD) && make )
|
||||
|
||||
install: configured
|
||||
( cd $(BUILD) && make install )
|
||||
|
||||
clean: configured
|
||||
( cd $(BUILD) && make clean )
|
||||
|
||||
dist: cmake_version
|
||||
# Minimum Bro source package
|
||||
( \
|
||||
./configure --ignore-dirs='aux/broctl;aux/broccoli' --pkg-name-prefix=Bro && \
|
||||
cd $(BUILD) && \
|
||||
make package_source \
|
||||
)
|
||||
# Full Bro source package
|
||||
( \
|
||||
./configure --pkg-name-prefix=Bro-all && \
|
||||
cd $(BUILD) && \
|
||||
make package_source \
|
||||
)
|
||||
# Broccoli source package
|
||||
( \
|
||||
cd $(BROCCOLI) && \
|
||||
./configure && \
|
||||
cd $(BUILD) && \
|
||||
make package_source && \
|
||||
mv Broccoli*.tar.gz ../../../$(BUILD)/ && \
|
||||
cd .. && \
|
||||
rm -r $(BUILD) \
|
||||
)
|
||||
# Broctl source package
|
||||
( \
|
||||
cd $(BROCTL) && \
|
||||
./configure && \
|
||||
cd $(BUILD) && \
|
||||
make package_source && \
|
||||
mv Broctl*.tar.gz ../../../$(BUILD)/ && \
|
||||
cd .. && \
|
||||
rm -r $(BUILD) \
|
||||
)
|
||||
|
||||
distclean:
|
||||
rm -rf $(BUILD)
|
||||
|
||||
configured:
|
||||
@test -d $(BUILD) || ( echo "Error: No build/ directory found. Did you run configure?" && exit 1 )
|
||||
@test -e $(BUILD)/Makefile || ( echo "Error: No build/Makefile found. Did you run configure?" && exit 1 )
|
||||
|
||||
cmake_version:
|
||||
@test "$(CMAKE_VER)" \> "cmake version $(CMAKE_PACK_REQ)" || ( echo "Error: please use a CMake version greater than $(CMAKE_PACK_REQ)" && exit 1 )
|
||||
|
||||
.PHONY : all install clean distclean configured cmake_version
|
64
Makefile.am
64
Makefile.am
|
@ -1,64 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# snag the whole linux-include directory
|
||||
EXTRA_DIST = CHANGES README VERSION shtool linux-include \
|
||||
autogen.sh depcomp ylwrap
|
||||
|
||||
# When running distcheck, make sure we skip building GtkDoc-based
|
||||
# documentation. This applies to Broccoli only, and needs to be
|
||||
# duplicated here because DISTCHECK_CONFIGURE_FLAGS isn't otherwise
|
||||
# noticed.
|
||||
#
|
||||
DISTCHECK_CONFIGURE_FLAGS = --disable-gtk-doc
|
||||
|
||||
chown = @CHOWN@
|
||||
|
||||
# aux before src so we compile the libpcap
|
||||
SUBDIRS = aux src scripts policy doc
|
||||
|
||||
test:
|
||||
( cd ../testing && $(MAKE) test )
|
||||
|
||||
install-broctl:
|
||||
$(MAKE) install
|
||||
( cd aux/broctl && $(MAKE) install-broctl )
|
||||
|
||||
# Deprecated. Don't use.
|
||||
install-brolite:
|
||||
$(MAKE) install
|
||||
$(INSTALL) -d $(prefix)/logs
|
||||
$(INSTALL) -d $(prefix)/archive
|
||||
$(INSTALL) -d $(prefix)/var
|
||||
( cd scripts && $(MAKE) install-brolite )
|
||||
( cd aux && $(MAKE) install-brolite )
|
||||
- @CHOWN@ -R `cat scripts/bro_user_id` ${prefix}/
|
||||
@echo "*********************************************************"
|
||||
@echo "Please run \"${prefix}/etc/bro.rc --start\" to start bro"
|
||||
@echo "*********************************************************"
|
||||
|
||||
docs:
|
||||
( cd doc && $(MAKE) doc )
|
||||
|
||||
doc-install:
|
||||
( cd doc && $(MAKE) doc-install )
|
||||
|
||||
update:
|
||||
( cd scripts && $(MAKE) update )
|
||||
( cd policy && $(MAKE) install )
|
||||
|
||||
update-sigs:
|
||||
(cd scripts && $(MAKE) update-sigs )
|
||||
|
||||
reports:
|
||||
( cd scripts && $(MAKE) reports )
|
||||
|
||||
# make sure we don't leak CVS/SVN or private policy files
|
||||
dist-hook:
|
||||
rm -rf `find $(distdir) -name CVS`
|
||||
rm -rf `find $(distdir) -name .svn`
|
||||
rm -rf $(distdir)/policy/local
|
||||
|
||||
release:
|
||||
./autogen.sh
|
||||
./configure
|
||||
$(MAKE) distcheck
|
0
NEWS
0
NEWS
29
README
29
README
|
@ -1,29 +1,24 @@
|
|||
This is release 1.5 of Bro, a system for detecting network intruders in
|
||||
This is release 1.6 of Bro, a system for detecting network intruders in
|
||||
real-time using passive network monitoring.
|
||||
|
||||
Please see the file INSTALL for installation instructions and some examples
|
||||
on how to run Bro. For more documentation, see the Bro Wiki:
|
||||
Please see the file INSTALL for installation instructions and
|
||||
pointers for getting started. For more documentation, see the
|
||||
documentation on Bro's home page:
|
||||
|
||||
http://www.bro-ids.org/wiki/index.php/User_Manual
|
||||
http://www.bro-ids.org/docs
|
||||
|
||||
Please note that this documentation is preliminary and still missing pieces.
|
||||
PDF and HTML versions of older versions of the manuals are also available
|
||||
in the doc/ directory.
|
||||
|
||||
There's also in doc/misc/conn-logs/ a brief summary of the connection logs
|
||||
generated by the sample policy scripts (which are in policy/).
|
||||
The main parts of Bro's documentation are also available in the doc/
|
||||
directory of the distribution. (Please note that the documentation
|
||||
is still a work in progress; there will be more in future releases.)
|
||||
|
||||
Numerous other Bro-related publications, including a paper describing the
|
||||
system, can be found at
|
||||
|
||||
http://www.bro-ids.org/publications.html
|
||||
http://www.bro-ids.org/publications.html
|
||||
|
||||
Some auxiliary scripts and utilities are available in the aux/ directory.
|
||||
Note that these are not installed by default.
|
||||
|
||||
Send comments, etc., to the Bro mailing list, bro@bro-ids.org. However,
|
||||
please note that you must first subscribe to the list in order to be able
|
||||
to post to it.
|
||||
Send comments, etc., to the Bro mailing list, bro@bro-ids.org.
|
||||
However, please note that you must first subscribe to the list in
|
||||
order to be able to post to it.
|
||||
|
||||
- Vern Paxson & Robin Sommer, on behalf of the Bro development team
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
Plan for 1.6:
|
||||
Originally, with 1.5 we were going to start working with --use-binpac
|
||||
as the default. However, this has been deferred pending development
|
||||
of BinPAC++. We might however turn on BinPAC for the SSL analyzer,
|
||||
for which the BinPAC version is more robust. It, though, doesn't
|
||||
support storing certs to disk, which some folks use operationally.
|
||||
|
||||
Given DPD means we might not filter traffic anyway, we no longer
|
||||
have such a good excuse for not dealing with IPv6 options.
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
1.5.2.7
|
||||
1.6-dev.4
|
||||
|
|
1007
acinclude.m4
1007
acinclude.m4
File diff suppressed because it is too large
Load diff
143
autogen.sh
143
autogen.sh
|
@ -1,143 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Initialization script to set up the initial configuration files etc.
|
||||
# shtool usage inspired by the autogen script of the ferite scripting
|
||||
# language -- cheers Chris :)
|
||||
#
|
||||
# This is 'borrowed' from netdude, with minor changes for bro
|
||||
|
||||
BLD_ON=`./shtool echo -n -e %B`
|
||||
BLD_OFF=`./shtool echo -n -e %b`
|
||||
|
||||
srcdir=`dirname $0`
|
||||
NAME=bro
|
||||
|
||||
DIE=0
|
||||
|
||||
echo
|
||||
echo " "${BLD_ON}"BRO Build Tools Setup"${BLD_OFF}
|
||||
echo "===================================================="
|
||||
echo
|
||||
echo "Checking whether we have all tools available ..."
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`autoconf' installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`automake' installed."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
NO_AUTOMAKE=yes
|
||||
}
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo ${BLD_ON}"Error"${BLD_OFF}": Missing \`aclocal'. The version of \`automake'"
|
||||
echo "installed doesn't appear recent enough."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All necessary tools found."
|
||||
echo
|
||||
|
||||
if [ -d autom4te.cache ] ; then
|
||||
echo "Removing autom4te.cache ..."
|
||||
rm -rf autom4te.cache
|
||||
#echo
|
||||
#echo ${BLD_ON}"Error"${BLD_OFF}": autom4te.cache directory exists"
|
||||
#echo "please remove it, and rerun this script"
|
||||
#echo
|
||||
#exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"aclocal"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
aclocal -I . $ACLOCAL_FLAGS
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"autoheader"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
autoheader
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"automake"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
automake -a -c
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"autoconf"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
autoconf
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Running aux/binpac/autogen.sh"
|
||||
echo "----------------------------------------------------"
|
||||
(cd aux/binpac/ && BROBUILD=yes ./autogen.sh)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Running aux/broccoli/autogen.sh"
|
||||
echo "----------------------------------------------------"
|
||||
(cd aux/broccoli/ && BROBUILD=yes ./autogen.sh)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Running aux/broctl/aux/capstats/autogen.sh"
|
||||
echo "----------------------------------------------------"
|
||||
(cd aux/broctl/aux/capstats && ./autogen.sh)
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "Setup finished. Now run:"
|
||||
echo
|
||||
echo " $ "${BLD_ON}"./configure"${BLD_OFF}" (with options as needed, try --help)"
|
||||
echo
|
||||
echo "and then"
|
||||
echo
|
||||
echo " $ "${BLD_ON}"make"${BLD_OFF}
|
||||
echo " # "${BLD_ON}"make install"${BLD_OFF}
|
||||
echo
|
|
@ -1,77 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
LIBPCAP_VER = libpcap-0.9.8
|
||||
LIBPCAP_LIB = $(LIBPCAP_VER)/libpcap.a
|
||||
|
||||
EXTRA_DIST = README $(LIBPCAP_VER).tar.gz
|
||||
|
||||
# if we don't have ssl, can't build bdcat
|
||||
if USE_SSL
|
||||
bdcat_dir = bdcat
|
||||
else
|
||||
bdcat_dir =
|
||||
endif
|
||||
|
||||
# don't compile libpcap if they did a '--disable-localpcap' to configure
|
||||
if USE_LOCALPCAP
|
||||
built_srcs = $(LIBPCAP_LIB)
|
||||
LARGE_FILE = "-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
|
||||
else
|
||||
built_srcs =
|
||||
endif
|
||||
|
||||
if USEV6
|
||||
PCAPARGS = --enable-ipv6
|
||||
else
|
||||
PCAPARGS =
|
||||
endif
|
||||
|
||||
if USE_BROCCOLI
|
||||
broccoli = broccoli
|
||||
else
|
||||
broccoli =
|
||||
endif
|
||||
|
||||
if USE_BROCTL
|
||||
broctl = broctl
|
||||
else
|
||||
broctl =
|
||||
endif
|
||||
|
||||
BUILT_SOURCES = $(built_srcs)
|
||||
|
||||
SUBDIRS = adtrace binpac cf hf nftools rst scripts \
|
||||
$(bdcat_dir) $(broccoli) $(broctl)
|
||||
|
||||
DIST_SUBDIRS = adtrace binpac cf hf nftools rst scripts \
|
||||
$(bdcat_dir) $(broccoli) $(broctl)
|
||||
|
||||
clean-local:
|
||||
rm -rf $(LIBPCAP_VER)
|
||||
|
||||
|
||||
$(LIBPCAP_LIB): $(top_srcdir)/aux/$(LIBPCAP_VER).tar.gz
|
||||
@echo "Unpacking libpcap sources"
|
||||
@gzip -d < $(top_srcdir)/aux/$(LIBPCAP_VER).tar.gz | tar xf -
|
||||
@echo "Building libpcap"
|
||||
( cd $(LIBPCAP_VER) && ./configure --prefix=$(prefix) $(PCAPARGS) CFLAGS=$(LARGE_FILE) && $(MAKE) )
|
||||
@chmod -R 755 $(LIBPCAP_VER)
|
||||
|
||||
|
||||
# This is a hack. These are hardcoded here to mimic the previous
|
||||
# brolite installation. While these should better go into the
|
||||
# subdirs' Makefile.am, it's not really worth the effort as
|
||||
# we will get rid of all this at some point anyway.
|
||||
install-brolite:
|
||||
$(INSTALL) ./hf/hf ${bindir}
|
||||
$(INSTALL) ./hf/nf ${bindir}
|
||||
$(INSTALL) ./hf/pf ${bindir}
|
||||
$(INSTALL) ./cf/cf ${bindir}
|
||||
$(INSTALL) ./rst/rst ${bindir}
|
||||
- install -d $(prefix)/scripts/
|
||||
$(INSTALL) ./scripts/host-to-addrs $(prefix)/scripts
|
||||
$(INSTALL) ./scripts/bro-logchk.pl $(prefix)/scripts
|
||||
$(INSTALL) ./scripts/host-grep $(prefix)/scripts
|
||||
$(INSTALL) ./scripts/mvlog $(prefix)/scripts
|
||||
|
||||
|
61
aux/README
61
aux/README
|
@ -1,61 +0,0 @@
|
|||
This directory contains handy auxiliary programs:
|
||||
|
||||
adtrace/
|
||||
Makefile and source for the adtrace utility. This program is used
|
||||
in conjunction with the localnetMAC.pl perl script to compute the
|
||||
network address that compose the internal and extern nets that bro
|
||||
is monitoring. This program when run by itself just reads a pcap
|
||||
(tcpcump) file and writes out the src MAC, dst MAC, src IP, dst
|
||||
IP for each packet seen in the file. This output is processed by
|
||||
the localnetMAC.pl script during 'make install'.
|
||||
|
||||
bdcat/
|
||||
A utility for decrypting encrypted Bro log files.
|
||||
|
||||
binpac/
|
||||
A compiler for generating protocol analyzers from high-level,
|
||||
declarative specifications. Used extensively for constructing
|
||||
Bro's protocol analyzers, but capable of stand-alone use for
|
||||
building analyzers outside of the Bro system.
|
||||
|
||||
broccoli/
|
||||
A C client library for interfacing programs with the Bro system.
|
||||
Enables sending and receiving of Bro values and events.
|
||||
|
||||
cf/
|
||||
Makefile and source for the "cf" utility. cf reads lines from
|
||||
stdin and if the line begins with a number, then it assumes that
|
||||
the number corresponds to a Unix timestamp and replaces it with
|
||||
the corresponding local time in a readable format. Useful for
|
||||
running on log files. See cf/cf.man.txt for documentation.
|
||||
|
||||
contrib/
|
||||
Unsupported contributions to Bro.
|
||||
|
||||
hf/
|
||||
The main utility in this subdirectory is hf, which translates
|
||||
any dotted-quad (in text) appearing on stdin to the corresponding
|
||||
DNS hostname (via a PTR lookup) on stdout.
|
||||
|
||||
nftools/
|
||||
Utilities for dealing with Bro's custom file format for storing
|
||||
NetFlow records. nfcollector reads NetFlow data from a socket
|
||||
and writes it in Bro's format. ftwire2bro reads NetFlow "wire"
|
||||
format (e.g., as generated by a 'flow-export' directive) and writes
|
||||
it in Bro's format.
|
||||
|
||||
rst/
|
||||
Makefile and source for the rst utility. "rst" can be invoked by
|
||||
a Bro script to terminate an established TCP connection by forging
|
||||
RST tear-down packets. See terminate_connection() in conn.bro.
|
||||
|
||||
scripts/
|
||||
A set of utility scripts for munching on Bro connection summaries.
|
||||
|
||||
bro_logchk: orders and scans through FTP and HTTP logs
|
||||
host-grep: greps a summary file for a particular host's activities
|
||||
host-to-addrs: converts a hostname to a list of IP addresses
|
||||
hot-report: formats a summary file in a readable fashion
|
||||
ip-grep: returns a grep pattern for a given IP address
|
||||
mon-report: summarizes a particular host's activity
|
||||
mvlog: compresses and archives log files
|
|
@ -1,10 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AM_CFLAGS=@V_INCLS@
|
||||
|
||||
# Should use AM_ vars, but automake 1.5 errors out.
|
||||
#AM_LDFLAGS = @LDFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
noinst_PROGRAMS = adtrace
|
||||
adtrace_SOURCES = adtrace.c ether.h ethertype.h ip.h
|
|
@ -1,92 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <pcap.h>
|
||||
|
||||
#include "../../config.h"
|
||||
#include "ip.h"
|
||||
#include "ether.h"
|
||||
#include "ethertype.h"
|
||||
|
||||
pcap_t *p;
|
||||
|
||||
const u_char* printEAddr(const u_char* pkt, u_char* endp){
|
||||
const struct ether_header *ep;
|
||||
int i=0;
|
||||
ep = (const struct ether_header*) pkt;
|
||||
|
||||
if (pkt+ETHER_HDRLEN > endp ||
|
||||
ntohs(ep->ether_type) != ETHERTYPE_IP){
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i<ETHER_ADDR_LEN; i++){
|
||||
if (i>0) putchar(':');
|
||||
printf("%02x", ep->ether_shost[i]);
|
||||
}
|
||||
putchar (' ');
|
||||
for (i = 0; i<ETHER_ADDR_LEN; i++){
|
||||
if (i>0) putchar(':');
|
||||
printf("%02x", ep->ether_dhost[i]);
|
||||
}
|
||||
putchar(' ');
|
||||
return (pkt+ETHER_HDRLEN);
|
||||
}
|
||||
|
||||
void printIPAddr(const u_char* pkt, u_char* endp){
|
||||
const struct ip* iph;
|
||||
if (pkt+sizeof(struct ip) > endp) return;
|
||||
iph = (const struct ip*) pkt;
|
||||
fputs ((char*) inet_ntoa(iph->ip_src), stdout);
|
||||
putchar(' ');
|
||||
puts ((char*) inet_ntoa(iph->ip_dst));
|
||||
}
|
||||
|
||||
void handler(u_char *user, const struct pcap_pkthdr *head, const u_char *packet){
|
||||
u_char* endp;
|
||||
|
||||
endp =(u_char*) packet + head->caplen;
|
||||
packet = printEAddr(packet, endp);
|
||||
if (packet)
|
||||
printIPAddr(packet, endp);
|
||||
}
|
||||
|
||||
void usage(char *av[])
|
||||
{
|
||||
fprintf(stderr,"usage: %s filename \n", av[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
char *file;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
u_char* pkt, endp;
|
||||
struct pcap_pkthdr *head;
|
||||
|
||||
if ( argc != 2 )
|
||||
usage(argv);
|
||||
|
||||
file = argv[1];
|
||||
|
||||
p = pcap_open_offline(file, errbuf);
|
||||
if(p==NULL){
|
||||
fprintf (stderr, "cannot open %s: %s\n", file, errbuf);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (pcap_datalink(p) != DLT_EN10MB){
|
||||
fputs ("sorry, currently only ethernet links supported\n", stderr);
|
||||
exit(1); //if it is not ethernet we are watching we won't have MACs
|
||||
}
|
||||
|
||||
pcap_loop(p, -1, handler, NULL);
|
||||
pcap_close(p);
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* @(#) $Header$ (LBL) */
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_ether.h 8.3 (Berkeley) 5/2/95
|
||||
*/
|
||||
|
||||
#define ETHERMTU 1500
|
||||
|
||||
/*
|
||||
* The number of bytes in an ethernet (MAC) address.
|
||||
*/
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
/*
|
||||
* Structure of a DEC/Intel/Xerox or 802.3 Ethernet header.
|
||||
*/
|
||||
struct ether_header {
|
||||
u_int8_t ether_dhost[ETHER_ADDR_LEN];
|
||||
u_int8_t ether_shost[ETHER_ADDR_LEN];
|
||||
u_int16_t ether_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Length of a DEC/Intel/Xerox or 802.3 Ethernet header; note that some
|
||||
* compilers may pad "struct ether_header" to a multiple of 4 bytes,
|
||||
* for example, so "sizeof (struct ether_header)" may not give the right
|
||||
* answer.
|
||||
*/
|
||||
#define ETHER_HDRLEN 14
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1993, 1994, 1996
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* @(#) $Header$ (LBL)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ethernet types.
|
||||
*
|
||||
* We wrap the declarations with #ifdef, so that if a file includes
|
||||
* <netinet/if_ether.h>, which may declare some of these, we don't
|
||||
* get a bunch of complaints from the C compiler about redefinitions
|
||||
* of these values.
|
||||
*
|
||||
* We declare all of them here so that no file has to include
|
||||
* <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
|
||||
*/
|
||||
|
||||
#ifndef ETHERTYPE_PUP
|
||||
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_IP
|
||||
#define ETHERTYPE_IP 0x0800 /* IP protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_ARP
|
||||
#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_REVARP
|
||||
#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
|
||||
#endif
|
||||
#ifndef ETHERTYPE_NS
|
||||
#define ETHERTYPE_NS 0x0600
|
||||
#endif
|
||||
#ifndef ETHERTYPE_SPRITE
|
||||
#define ETHERTYPE_SPRITE 0x0500
|
||||
#endif
|
||||
#ifndef ETHERTYPE_TRAIL
|
||||
#define ETHERTYPE_TRAIL 0x1000
|
||||
#endif
|
||||
#ifndef ETHERTYPE_MOPDL
|
||||
#define ETHERTYPE_MOPDL 0x6001
|
||||
#endif
|
||||
#ifndef ETHERTYPE_MOPRC
|
||||
#define ETHERTYPE_MOPRC 0x6002
|
||||
#endif
|
||||
#ifndef ETHERTYPE_DN
|
||||
#define ETHERTYPE_DN 0x6003
|
||||
#endif
|
||||
#ifndef ETHERTYPE_LAT
|
||||
#define ETHERTYPE_LAT 0x6004
|
||||
#endif
|
||||
#ifndef ETHERTYPE_SCA
|
||||
#define ETHERTYPE_SCA 0x6007
|
||||
#endif
|
||||
#ifndef ETHERTYPE_REVARP
|
||||
#define ETHERTYPE_REVARP 0x8035
|
||||
#endif
|
||||
#ifndef ETHERTYPE_LANBRIDGE
|
||||
#define ETHERTYPE_LANBRIDGE 0x8038
|
||||
#endif
|
||||
#ifndef ETHERTYPE_DECDNS
|
||||
#define ETHERTYPE_DECDNS 0x803c
|
||||
#endif
|
||||
#ifndef ETHERTYPE_DECDTS
|
||||
#define ETHERTYPE_DECDTS 0x803e
|
||||
#endif
|
||||
#ifndef ETHERTYPE_VEXP
|
||||
#define ETHERTYPE_VEXP 0x805b
|
||||
#endif
|
||||
#ifndef ETHERTYPE_VPROD
|
||||
#define ETHERTYPE_VPROD 0x805c
|
||||
#endif
|
||||
#ifndef ETHERTYPE_ATALK
|
||||
#define ETHERTYPE_ATALK 0x809b
|
||||
#endif
|
||||
#ifndef ETHERTYPE_AARP
|
||||
#define ETHERTYPE_AARP 0x80f3
|
||||
#endif
|
||||
#ifndef ETHERTYPE_8021Q
|
||||
#define ETHERTYPE_8021Q 0x8100
|
||||
#endif
|
||||
#ifndef ETHERTYPE_IPX
|
||||
#define ETHERTYPE_IPX 0x8137
|
||||
#endif
|
||||
#ifndef ETHERTYPE_IPV6
|
||||
#define ETHERTYPE_IPV6 0x86dd
|
||||
#endif
|
||||
#ifndef ETHERTYPE_PPP
|
||||
#define ETHERTYPE_PPP 0x880b
|
||||
#endif
|
||||
#ifndef ETHERTYPE_MPLS
|
||||
#define ETHERTYPE_MPLS 0x8847
|
||||
#endif
|
||||
#ifndef ETHERTYPE_MPLS_MULTI
|
||||
#define ETHERTYPE_MPLS_MULTI 0x8848
|
||||
#endif
|
||||
#ifndef ETHERTYPE_PPPOED
|
||||
#define ETHERTYPE_PPPOED 0x8863
|
||||
#endif
|
||||
#ifndef ETHERTYPE_PPPOES
|
||||
#define ETHERTYPE_PPPOES 0x8864
|
||||
#endif
|
||||
#ifndef ETHERTYPE_LOOPBACK
|
||||
#define ETHERTYPE_LOOPBACK 0x9000
|
||||
#endif
|
159
aux/adtrace/ip.h
159
aux/adtrace/ip.h
|
@ -1,159 +0,0 @@
|
|||
/* @(#) $Header$ (LBL) */
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip.h 8.2 (Berkeley) 6/1/94
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definitions for internet protocol version 4.
|
||||
* Per RFC 791, September 1981.
|
||||
*/
|
||||
#define IPVERSION 4
|
||||
|
||||
/*
|
||||
* Structure of an internet header, naked of options.
|
||||
*
|
||||
* We declare ip_len and ip_off to be short, rather than u_short
|
||||
* pragmatically since otherwise unsigned comparisons can result
|
||||
* against negative integers quite easily, and fail in subtle ways.
|
||||
*/
|
||||
struct ip {
|
||||
u_int8_t ip_vhl; /* header length, version */
|
||||
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
|
||||
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
|
||||
u_int8_t ip_tos; /* type of service */
|
||||
u_int16_t ip_len; /* total length */
|
||||
u_int16_t ip_id; /* identification */
|
||||
u_int16_t ip_off; /* fragment offset field */
|
||||
#define IP_DF 0x4000 /* dont fragment flag */
|
||||
#define IP_MF 0x2000 /* more fragments flag */
|
||||
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
|
||||
u_int8_t ip_ttl; /* time to live */
|
||||
u_int8_t ip_p; /* protocol */
|
||||
u_int16_t ip_sum; /* checksum */
|
||||
struct in_addr ip_src,ip_dst; /* source and dest address */
|
||||
};
|
||||
|
||||
#define IP_MAXPACKET 65535 /* maximum packet size */
|
||||
|
||||
/*
|
||||
* Definitions for IP type of service (ip_tos)
|
||||
*/
|
||||
#define IPTOS_LOWDELAY 0x10
|
||||
#define IPTOS_THROUGHPUT 0x08
|
||||
#define IPTOS_RELIABILITY 0x04
|
||||
|
||||
/*
|
||||
* Definitions for IP precedence (also in ip_tos) (hopefully unused)
|
||||
*/
|
||||
#define IPTOS_PREC_NETCONTROL 0xe0
|
||||
#define IPTOS_PREC_INTERNETCONTROL 0xc0
|
||||
#define IPTOS_PREC_CRITIC_ECP 0xa0
|
||||
#define IPTOS_PREC_FLASHOVERRIDE 0x80
|
||||
#define IPTOS_PREC_FLASH 0x60
|
||||
#define IPTOS_PREC_IMMEDIATE 0x40
|
||||
#define IPTOS_PREC_PRIORITY 0x20
|
||||
#define IPTOS_PREC_ROUTINE 0x00
|
||||
|
||||
/*
|
||||
* Definitions for options.
|
||||
*/
|
||||
#define IPOPT_COPIED(o) ((o)&0x80)
|
||||
#define IPOPT_CLASS(o) ((o)&0x60)
|
||||
#define IPOPT_NUMBER(o) ((o)&0x1f)
|
||||
|
||||
#define IPOPT_CONTROL 0x00
|
||||
#define IPOPT_RESERVED1 0x20
|
||||
#define IPOPT_DEBMEAS 0x40
|
||||
#define IPOPT_RESERVED2 0x60
|
||||
|
||||
#define IPOPT_EOL 0 /* end of option list */
|
||||
#define IPOPT_NOP 1 /* no operation */
|
||||
|
||||
#define IPOPT_RR 7 /* record packet route */
|
||||
#define IPOPT_TS 68 /* timestamp */
|
||||
#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
|
||||
#define IPOPT_LSRR 131 /* loose source route */
|
||||
#define IPOPT_SATID 136 /* satnet id */
|
||||
#define IPOPT_SSRR 137 /* strict source route */
|
||||
|
||||
/*
|
||||
* Offsets to fields in options other than EOL and NOP.
|
||||
*/
|
||||
#define IPOPT_OPTVAL 0 /* option ID */
|
||||
#define IPOPT_OLEN 1 /* option length */
|
||||
#define IPOPT_OFFSET 2 /* offset within option */
|
||||
#define IPOPT_MINOFF 4 /* min value of above */
|
||||
|
||||
/*
|
||||
* Time stamp option structure.
|
||||
*/
|
||||
struct ip_timestamp {
|
||||
u_int8_t ipt_code; /* IPOPT_TS */
|
||||
u_int8_t ipt_len; /* size of structure (variable) */
|
||||
u_int8_t ipt_ptr; /* index of current entry */
|
||||
u_int8_t ipt_oflwflg; /* flags, overflow counter */
|
||||
#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4)
|
||||
#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f)
|
||||
union ipt_timestamp {
|
||||
u_int32_t ipt_time[1];
|
||||
struct ipt_ta {
|
||||
struct in_addr ipt_addr;
|
||||
u_int32_t ipt_time;
|
||||
} ipt_ta[1];
|
||||
} ipt_timestamp;
|
||||
};
|
||||
|
||||
/* flag bits for ipt_flg */
|
||||
#define IPOPT_TS_TSONLY 0 /* timestamps only */
|
||||
#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
|
||||
#define IPOPT_TS_PRESPEC 3 /* specified modules only */
|
||||
|
||||
/* bits for security (not byte swapped) */
|
||||
#define IPOPT_SECUR_UNCLASS 0x0000
|
||||
#define IPOPT_SECUR_CONFID 0xf135
|
||||
#define IPOPT_SECUR_EFTO 0x789a
|
||||
#define IPOPT_SECUR_MMMM 0xbc4d
|
||||
#define IPOPT_SECUR_RESTR 0xaf13
|
||||
#define IPOPT_SECUR_SECRET 0xd788
|
||||
#define IPOPT_SECUR_TOPSECRET 0x6bc5
|
||||
|
||||
/*
|
||||
* Internet implementation parameters.
|
||||
*/
|
||||
#define MAXTTL 255 /* maximum time to live (seconds) */
|
||||
#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
|
||||
#define IPFRAGTTL 60 /* time to live for frags, slowhz */
|
||||
#define IPTTLDEC 1 /* subtracted when forwarding */
|
||||
|
||||
#define IP_MSS 576 /* default maximum segment size */
|
|
@ -1,4 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_PROGRAMS = bdcat
|
||||
bdcat_SOURCES = bdcat.cc
|
|
@ -1,175 +0,0 @@
|
|||
// $Id: bdcat.cc 6 2004-04-30 00:31:26Z jason $
|
||||
//
|
||||
// Decrypts Bro's log files.
|
||||
//
|
||||
// Usage: bdcat [-k file-with-secret-rsa-key] [files...]
|
||||
//
|
||||
// The key file may be alternatively set via the env variable BDCAT_KEY.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "openssl/evp.h"
|
||||
#include "openssl/pem.h"
|
||||
#include "openssl/err.h"
|
||||
|
||||
EVP_PKEY* SecKey = 0;
|
||||
EVP_CIPHER* CipherType = 0;
|
||||
|
||||
void cryptcat(FILE* f)
|
||||
{
|
||||
unsigned char magic[7];
|
||||
unsigned long secret_len;
|
||||
|
||||
// Read file header.
|
||||
if ( ! (fread(&magic, 7, 1, f) &&
|
||||
fread(&secret_len, sizeof(secret_len), 1, f)) )
|
||||
{
|
||||
fprintf(stderr, "can't read file header: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( memcmp("BROENC1", (const char*) magic, 7) != 0 )
|
||||
{
|
||||
fputs("not a Bro encrypted file\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
secret_len = ntohl(secret_len);
|
||||
int iv_len = EVP_CIPHER_iv_length(CipherType);
|
||||
unsigned char secret[secret_len];
|
||||
unsigned char iv[iv_len];
|
||||
|
||||
if ( ! (fread(&secret, secret_len, 1, f) &&
|
||||
fread(&iv, iv_len, 1, f)) )
|
||||
{
|
||||
fprintf(stderr, "can't read file header: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Decrypt data.
|
||||
EVP_CIPHER_CTX cipher_ctx;
|
||||
if ( ! EVP_OpenInit(&cipher_ctx, CipherType,
|
||||
secret, secret_len, iv, SecKey) )
|
||||
{
|
||||
fprintf( stderr, "can't init decryption: %s\n",
|
||||
ERR_error_string(ERR_get_error(), 0));
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
int block_size = EVP_CIPHER_block_size(CipherType);
|
||||
unsigned char buffer_in[block_size];
|
||||
unsigned char buffer_out[block_size];
|
||||
|
||||
int inl, outl;
|
||||
while ( (inl = fread(buffer_in, 1, block_size, f)) )
|
||||
{
|
||||
if ( ! EVP_OpenUpdate(&cipher_ctx, buffer_out,
|
||||
&outl, buffer_in, inl) )
|
||||
{
|
||||
fprintf( stderr, "can't decrypt: %s\n",
|
||||
ERR_error_string(ERR_get_error(), 0));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( outl && ! fwrite(buffer_out, outl, 1, stdout) )
|
||||
{
|
||||
fprintf(stderr, "can't write to stdout: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! EVP_OpenFinal(&cipher_ctx, buffer_out, &outl) )
|
||||
{
|
||||
fprintf( stderr, "can't decrypt: %s\n",
|
||||
ERR_error_string(ERR_get_error(), 0));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( outl && ! fwrite(buffer_out, outl, 1, stdout) )
|
||||
{
|
||||
fprintf(stderr, "can't write to stdout: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void Usage()
|
||||
{
|
||||
fprintf(stderr, "bdcat [-k <sec-key-file>] [files]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char* keyfile = getenv("BDCAT_KEY");
|
||||
|
||||
// Read options.
|
||||
char op;
|
||||
while ( (op = getopt(argc, argv, "k:")) >= 0 )
|
||||
{
|
||||
if ( op == 'k' )
|
||||
keyfile = optarg;
|
||||
else
|
||||
Usage();
|
||||
}
|
||||
|
||||
if ( ! keyfile )
|
||||
{
|
||||
fputs("no keyfile given\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Init crypto.
|
||||
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
FILE* f = fopen(keyfile, "r");
|
||||
if ( ! f )
|
||||
{
|
||||
fprintf(stderr, "can't open key file %s: %s\n",
|
||||
keyfile, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SecKey = PEM_read_PrivateKey(f, 0, 0, 0);
|
||||
if ( ! SecKey )
|
||||
{
|
||||
fprintf(stderr, "can't read key from %s: %s\n", keyfile,
|
||||
ERR_error_string(ERR_get_error(), 0));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
// Depending on the OpenSSL version, EVP_*_cbc()
|
||||
// returns a const or a non-const.
|
||||
CipherType = (EVP_CIPHER*) EVP_bf_cbc();
|
||||
|
||||
// Decrypt the files.
|
||||
if ( optind == argc )
|
||||
cryptcat(stdin);
|
||||
else
|
||||
{
|
||||
while ( optind < argc )
|
||||
{
|
||||
FILE* f = fopen(argv[optind], "r");
|
||||
if ( ! f )
|
||||
{
|
||||
fprintf(stderr, "can't open %s: %s\n",
|
||||
argv[optind], strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cryptcat(f);
|
||||
++optind;
|
||||
}
|
||||
}
|
||||
}
|
1
aux/binpac
Submodule
1
aux/binpac
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 7bbd3b14c02321ff2a63d7267e9ae022bda4f5bc
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright (c) 1995-2007
|
||||
// The Regents of the University of California. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that: (1) source code distributions
|
||||
// retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
// distributions including binary code include the above copyright notice and
|
||||
// this paragraph in its entirety in the documentation or other materials
|
||||
// provided with the distribution, and (3) all advertising materials mentioning
|
||||
// features or use of this software display the following acknowledgement:
|
||||
// ``This product includes software developed by the University of California,
|
||||
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
// the University nor the names of its contributors may be used to endorse
|
||||
// or promote products derived from this software without specific prior
|
||||
// written permission.
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
@ -1,231 +0,0 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 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=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
||||
use PREFIX 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=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--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.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
EXTRA_DIST = README VERSION CHANGES TODO depcomp shtool autogen.sh
|
||||
SUBDIRS = lib src
|
|
@ -1,34 +0,0 @@
|
|||
Big features
|
||||
* Variable context (xid, call in RPC)? -- no variable context
|
||||
* Helpers
|
||||
* Connection states and actions
|
||||
* Case and analyzer redef
|
||||
* &also withinput
|
||||
* Explicit analyzer context (interface + instantiation) "withcontext"
|
||||
+ Interface with C++ and Bro (events, extern, weird)
|
||||
+ Incremental input
|
||||
+ ASCII protocols
|
||||
+ Reassembly
|
||||
- Dealing with exceptions
|
||||
- Dependency analysis to save parsing time on unused fields
|
||||
- Performance measurement
|
||||
|
||||
Small features
|
||||
* Restructure the code: break up pac.{h,cc}
|
||||
* ref counting (to keep certain structures)
|
||||
* analyzer context as a parameter of class
|
||||
* &autolength
|
||||
* find a better name for "analyzer_context" ("analcxt", "context", "analyzer") $context
|
||||
* &if
|
||||
* &autolength (now &restofdata)
|
||||
* Use vector<> instead of array<>?
|
||||
* set end_of_data when &length = ...
|
||||
- make the `default' case mandatory?
|
||||
- &inline
|
||||
- &warn and &check? (follow &if)
|
||||
- typedef?
|
||||
|
||||
Binpac 1
|
||||
- create a namespace for each .pac file
|
||||
- type equivalence
|
||||
- byteorder() for every type?
|
|
@ -1 +0,0 @@
|
|||
0.1
|
|
@ -1,114 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Initialization script to set up the initial configuration files etc.
|
||||
# shtool usage inspired by the autogen script of the ferite scripting
|
||||
# language -- cheers Chris :)
|
||||
#
|
||||
# This is 'borrowed' from netdude, with minor changes for bro
|
||||
|
||||
BLD_ON=`./shtool echo -n -e %B`
|
||||
BLD_OFF=`./shtool echo -n -e %b`
|
||||
|
||||
srcdir=`dirname $0`
|
||||
NAME=binpac
|
||||
|
||||
DIE=0
|
||||
|
||||
echo
|
||||
echo " "${BLD_ON}"Binpac Build Tools Setup"${BLD_OFF}
|
||||
echo "===================================================="
|
||||
echo
|
||||
echo "Checking whether we have all tools available ..."
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`autoconf' installed to."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`automake' installed."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
NO_AUTOMAKE=yes
|
||||
}
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo ${BLD_ON}"Error"${BLD_OFF}": Missing \`aclocal'. The version of \`automake'"
|
||||
echo "installed doesn't appear recent enough."
|
||||
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
|
||||
echo "(or a newer version if it is available)"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All necessary tools found."
|
||||
echo
|
||||
|
||||
if [ -d autom4te.cache ] ; then
|
||||
echo "Removing autom4te.cache ..."
|
||||
rm -rf autom4te.cache
|
||||
#echo
|
||||
#echo ${BLD_ON}"Error"${BLD_OFF}": autom4te.cache directory exists"
|
||||
#echo "please remove it, and rerun this script"
|
||||
#echo
|
||||
#exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"aclocal"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
aclocal -I . $ACLOCAL_FLAGS
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"autoheader"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
autoheader
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"automake"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
automake -a -c
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "running "${BLD_ON}"autoconf"${BLD_OFF}
|
||||
echo "----------------------------------------------------"
|
||||
autoconf
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "*** ERROR($NAME), aborting."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! test "x$BROBUILD" = xyes; then
|
||||
echo
|
||||
echo "Setup finished. Now run:"
|
||||
echo
|
||||
echo " $ "${BLD_ON}"./configure"${BLD_OFF}" (with options as needed, try --help)"
|
||||
echo
|
||||
echo "and then"
|
||||
echo
|
||||
echo " $ "${BLD_ON}"make"${BLD_OFF}
|
||||
echo " # "${BLD_ON}"make install"${BLD_OFF}
|
||||
echo
|
||||
fi
|
|
@ -1,55 +0,0 @@
|
|||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([src/pac_main.cc])
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
|
||||
AC_CONFIG_AUX_DIR(.)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
AM_INIT_AUTOMAKE(binpac, esyscmd([tr -d '\n' < VERSION]))
|
||||
|
||||
dnl Commands for funkier shell output:
|
||||
BLD_ON=`./shtool echo -n -e %B`
|
||||
BLD_OFF=`./shtool echo -n -e %b`
|
||||
|
||||
dnl ################################################
|
||||
dnl # Checks for programs
|
||||
dnl ################################################
|
||||
AM_PROG_LEX
|
||||
AC_PROG_YACC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
|
||||
m4_ifdef([AC_COMPUTE_INT], [], [AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])])
|
||||
|
||||
AC_COMPUTE_INT([SIZEOF_UNSIGNED_INT], [sizeof(unsigned int)])
|
||||
AC_SUBST(SIZEOF_UNSIGNED_INT)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug no compiler optimizations],
|
||||
debug="yes"
|
||||
CFLAGS="-DDEBUG `echo $CFLAGS | sed -e 's/-O2//'`"
|
||||
CXXFLAGS="-DDEBUG `echo $CXXFLAGS | sed -e 's/-O2//'`",
|
||||
debug="no")
|
||||
|
||||
AC_C_BIGENDIAN(
|
||||
AC_DEFINE(WORDS_BIGENDIAN,1,[whether words are stored with the most significant byte first])
|
||||
dnl This is intentionally named differently so as to not collide with WORDS_BIGENDIAN
|
||||
HOST_BIGENDIAN="#define HOST_BIGENDIAN 1"
|
||||
AC_SUBST(HOST_BIGENDIAN))
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
lib/Makefile
|
||||
lib/binpac.h
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
echo
|
||||
echo " "${BLD_ON}"Binpac Configuration Summary"${BLD_OFF}
|
||||
echo "=========================================================="
|
||||
echo
|
||||
echo " - Debugging enabled: "${BLD_ON}$debug${BLD_OFF}
|
||||
echo
|
||||
exit 0
|
|
@ -1,8 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_LIBRARIES = libbinpac.a
|
||||
|
||||
libbinpac_a_SOURCES = \
|
||||
binpac_buffer.cc binpac_bytestring.cc \
|
||||
binpac.h binpac_analyzer.h binpac_buffer.h \
|
||||
binpac_bytestring.h binpac_exception.h binpac_regex.h
|
|
@ -1,3 +0,0 @@
|
|||
This directory contains a library needed by generated C++ code from
|
||||
binpac. Note that the library is not needed by the binpac compiler
|
||||
itself.
|
|
@ -1,142 +0,0 @@
|
|||
// $Id: binpac.h,v 1.1.4.2 2006/06/02 15:13:13 rpang Exp $
|
||||
// Do not edit binpac.h, edit binpac.h.in instead!
|
||||
|
||||
#ifndef binpac_h
|
||||
#define binpac_h
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
@HOST_BIGENDIAN@
|
||||
#ifdef HOST_BIGENDIAN
|
||||
# define HOST_BYTEORDER bigendian
|
||||
#else
|
||||
# define HOST_BYTEORDER littleendian
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#define BINPAC_ASSERT(x) assert(x)
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace binpac {
|
||||
|
||||
const int bigendian = 0;
|
||||
const int littleendian = 1;
|
||||
const int unspecified_byteorder = -1;
|
||||
|
||||
#ifndef pac_type_defs
|
||||
#define pac_type_defs
|
||||
|
||||
typedef char int8;
|
||||
typedef short int16;
|
||||
typedef long int32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef void *nullptr;
|
||||
typedef void *voidptr;
|
||||
typedef uint8 *byteptr;
|
||||
typedef const uint8 *const_byteptr;
|
||||
typedef const char *const_charptr;
|
||||
|
||||
#if @SIZEOF_UNSIGNED_INT@ != 4
|
||||
#error "unexpected size of unsigned int"
|
||||
#endif
|
||||
|
||||
#endif /* pac_type_defs */
|
||||
|
||||
/* Handling byte order */
|
||||
|
||||
namespace {
|
||||
|
||||
inline int16 pac_swap(int16 x)
|
||||
{
|
||||
return (x >> 8) | ((x & 0xff) << 8);
|
||||
}
|
||||
|
||||
inline uint16 pac_swap(uint16 x)
|
||||
{
|
||||
return (x >> 8) | ((x & 0xff) << 8);
|
||||
}
|
||||
|
||||
inline int32 pac_swap(int32 x)
|
||||
{
|
||||
return (x >> 24) |
|
||||
((x & 0xff0000) >> 8) |
|
||||
((x & 0xff00) << 8) |
|
||||
((x & 0xff) << 24);
|
||||
}
|
||||
|
||||
inline uint32 pac_swap(uint32 x)
|
||||
{
|
||||
return (x >> 24) |
|
||||
((x & 0xff0000) >> 8) |
|
||||
((x & 0xff00) << 8) |
|
||||
((x & 0xff) << 24);
|
||||
}
|
||||
|
||||
#define FixByteOrder(byteorder, x) (byteorder == HOST_BYTEORDER ? (x) : pac_swap(x))
|
||||
|
||||
template <class T>
|
||||
inline T UnMarshall(const u_char *data, int byteorder)
|
||||
{
|
||||
T result = 0;
|
||||
for ( int i = 0; i < (int) sizeof(T); ++i )
|
||||
result = ( result << 8 ) |
|
||||
data[byteorder == bigendian ? i : sizeof(T) - 1 - i];
|
||||
return result;
|
||||
}
|
||||
|
||||
inline const char* do_fmt(const char* format, va_list ap)
|
||||
{
|
||||
static char buf[1024];
|
||||
vsnprintf(buf, sizeof(buf), format, ap);
|
||||
return buf;
|
||||
}
|
||||
|
||||
inline string strfmt(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
const char* r = do_fmt(format, ap);
|
||||
va_end(ap);
|
||||
return string(r);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
#define binpac_fmt(x...) strfmt(x).c_str()
|
||||
|
||||
class RefCount
|
||||
{
|
||||
public:
|
||||
RefCount() { count = 1; }
|
||||
void Ref() { ++count; }
|
||||
int Unref() { BINPAC_ASSERT(count > 0); return --count; }
|
||||
|
||||
private:
|
||||
int count;
|
||||
};
|
||||
|
||||
namespace {
|
||||
inline void Unref(RefCount *x)
|
||||
{
|
||||
if ( x && x->Unref() <= 0 )
|
||||
delete x;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace binpac
|
||||
|
||||
#include "binpac_analyzer.h"
|
||||
#include "binpac_buffer.h"
|
||||
#include "binpac_bytestring.h"
|
||||
#include "binpac_exception.h"
|
||||
#include "binpac_regex.h"
|
||||
|
||||
#endif /* binpac_h */
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef binpac_an_h
|
||||
#define binpac_an_h
|
||||
|
||||
namespace binpac {
|
||||
|
||||
// TODO: Add the Done() function
|
||||
|
||||
// The interface for a connection analyzer
|
||||
class ConnectionAnalyzer {
|
||||
public:
|
||||
virtual ~ConnectionAnalyzer() {}
|
||||
virtual void NewData(bool is_orig,
|
||||
const u_char *begin_of_data,
|
||||
const u_char *end_of_data) = 0;
|
||||
};
|
||||
|
||||
// The interface for a flow analyzer
|
||||
class FlowAnalyzer {
|
||||
public:
|
||||
virtual ~FlowAnalyzer() {}
|
||||
virtual void NewData(const u_char *begin_of_data,
|
||||
const u_char *end_of_data) = 0;
|
||||
};
|
||||
|
||||
} // namespace binpac
|
||||
|
||||
#endif // binpac_an_h
|
|
@ -1,465 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
#define binpac_regex_h
|
||||
|
||||
#include "binpac.h"
|
||||
#include "binpac_buffer.h"
|
||||
|
||||
namespace binpac {
|
||||
|
||||
extern double network_time();
|
||||
|
||||
namespace {
|
||||
const u_char CR = '\r';
|
||||
const u_char LF = '\n';
|
||||
}
|
||||
|
||||
FlowBuffer::FlowBuffer(LineBreakStyle linebreak_style)
|
||||
{
|
||||
buffer_length_ = 0;
|
||||
buffer_ = 0;
|
||||
|
||||
orig_data_begin_ = 0;
|
||||
orig_data_end_ = 0;
|
||||
|
||||
linebreak_style_ = linebreak_style;
|
||||
ResetLineState();
|
||||
|
||||
mode_ = UNKNOWN_MODE;
|
||||
frame_length_ = 0;
|
||||
chunked_ = false;
|
||||
|
||||
data_seq_at_orig_data_end_ = 0;
|
||||
eof_ = false;
|
||||
have_pending_request_ = false;
|
||||
|
||||
buffer_n_ = 0;
|
||||
|
||||
NewMessage();
|
||||
}
|
||||
|
||||
FlowBuffer::~FlowBuffer()
|
||||
{
|
||||
if ( buffer_ )
|
||||
free(buffer_);
|
||||
}
|
||||
|
||||
void FlowBuffer::NewMessage()
|
||||
{
|
||||
BINPAC_ASSERT(frame_length_ >= 0);
|
||||
|
||||
int bytes_to_advance = 0;
|
||||
if ( buffer_n_ == 0 )
|
||||
{
|
||||
switch ( mode_ )
|
||||
{
|
||||
case LINE_MODE:
|
||||
bytes_to_advance = (frame_length_ +
|
||||
(linebreak_style_ == STRICT_CRLF ?
|
||||
2 : 1));
|
||||
break;
|
||||
case FRAME_MODE:
|
||||
bytes_to_advance = frame_length_;
|
||||
break;
|
||||
case UNKNOWN_MODE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
orig_data_begin_ += bytes_to_advance;
|
||||
BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_);
|
||||
|
||||
buffer_n_ = 0;
|
||||
message_complete_ = false;
|
||||
}
|
||||
|
||||
void FlowBuffer::ResetLineState()
|
||||
{
|
||||
switch ( linebreak_style_ )
|
||||
{
|
||||
case CR_OR_LF:
|
||||
state_ = CR_OR_LF_0;
|
||||
break;
|
||||
case STRICT_CRLF:
|
||||
state_ = STRICT_CRLF_0;
|
||||
break;
|
||||
default:
|
||||
BINPAC_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FlowBuffer::ExpandBuffer(int length)
|
||||
{
|
||||
if ( buffer_length_ >= length )
|
||||
return;
|
||||
// So length > 0
|
||||
if ( length < 512 )
|
||||
length = 512;
|
||||
|
||||
if ( length < buffer_length_ * 2 )
|
||||
length = buffer_length_ * 2;
|
||||
|
||||
// Allocate a new buffer and copy the existing contents
|
||||
buffer_length_ = length;
|
||||
u_char *new_buf = (u_char *) realloc(buffer_, buffer_length_);
|
||||
BINPAC_ASSERT(new_buf);
|
||||
#if 0
|
||||
u_char* new_buf = new u_char[buffer_length_];
|
||||
if ( buffer_ && buffer_n_ > 0 )
|
||||
memcpy(new_buf, buffer_, buffer_n_);
|
||||
delete [] buffer_;
|
||||
#endif
|
||||
buffer_ = new_buf;
|
||||
}
|
||||
|
||||
void FlowBuffer::NewLine()
|
||||
{
|
||||
FlowBuffer::NewMessage();
|
||||
mode_ = LINE_MODE;
|
||||
frame_length_ = 0;
|
||||
chunked_ = false;
|
||||
have_pending_request_ = true;
|
||||
if ( state_ == FRAME_0 )
|
||||
ResetLineState();
|
||||
MarkOrCopyLine();
|
||||
}
|
||||
|
||||
void FlowBuffer::NewFrame(int frame_length, bool chunked)
|
||||
{
|
||||
FlowBuffer::NewMessage();
|
||||
mode_ = FRAME_MODE;
|
||||
frame_length_ = frame_length;
|
||||
chunked_ = chunked;
|
||||
have_pending_request_ = true;
|
||||
MarkOrCopyFrame();
|
||||
}
|
||||
|
||||
void FlowBuffer::GrowFrame(int length)
|
||||
{
|
||||
BINPAC_ASSERT(frame_length_ >= 0);
|
||||
if ( length <= frame_length_ )
|
||||
return;
|
||||
BINPAC_ASSERT(! chunked_ || frame_length_ == 0);
|
||||
mode_ = FRAME_MODE;
|
||||
frame_length_ = length;
|
||||
MarkOrCopyFrame();
|
||||
}
|
||||
|
||||
void FlowBuffer::DiscardData()
|
||||
{
|
||||
mode_ = UNKNOWN_MODE;
|
||||
message_complete_ = false;
|
||||
have_pending_request_ = false;
|
||||
orig_data_begin_ = orig_data_end_ = 0;
|
||||
|
||||
buffer_n_ = 0;
|
||||
frame_length_ = 0;
|
||||
}
|
||||
|
||||
void FlowBuffer::set_eof()
|
||||
{
|
||||
// fprintf(stderr, "EOF\n");
|
||||
eof_ = true;
|
||||
if ( chunked_ )
|
||||
frame_length_ = orig_data_end_ - orig_data_begin_;
|
||||
if ( frame_length_ < 0 )
|
||||
frame_length_ = 0;
|
||||
}
|
||||
|
||||
void FlowBuffer::NewData(const_byteptr begin, const_byteptr end)
|
||||
{
|
||||
BINPAC_ASSERT(begin <= end);
|
||||
|
||||
ClearPreviousData();
|
||||
|
||||
BINPAC_ASSERT((buffer_n_ == 0 && message_complete_) ||
|
||||
orig_data_begin_ == orig_data_end_);
|
||||
|
||||
orig_data_begin_ = begin;
|
||||
orig_data_end_ = end;
|
||||
data_seq_at_orig_data_end_ += (end - begin);
|
||||
|
||||
MarkOrCopy();
|
||||
}
|
||||
|
||||
void FlowBuffer::MarkOrCopy()
|
||||
{
|
||||
if ( ! message_complete_ )
|
||||
{
|
||||
switch ( mode_ )
|
||||
{
|
||||
case LINE_MODE:
|
||||
MarkOrCopyLine();
|
||||
break;
|
||||
|
||||
case FRAME_MODE:
|
||||
MarkOrCopyFrame();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlowBuffer::ClearPreviousData()
|
||||
{
|
||||
// All previous data must have been processed or buffered already
|
||||
if ( orig_data_begin_ < orig_data_end_ )
|
||||
{
|
||||
BINPAC_ASSERT(buffer_n_ == 0);
|
||||
if ( chunked_ )
|
||||
{
|
||||
if ( frame_length_ > 0 )
|
||||
{
|
||||
frame_length_ -=
|
||||
(orig_data_end_ - orig_data_begin_);
|
||||
}
|
||||
orig_data_begin_ = orig_data_end_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlowBuffer::NewGap(int length)
|
||||
{
|
||||
ClearPreviousData();
|
||||
|
||||
if ( chunked_ && frame_length_ >= 0 )
|
||||
{
|
||||
frame_length_ -= length;
|
||||
if ( frame_length_ < 0 )
|
||||
frame_length_ = 0;
|
||||
}
|
||||
|
||||
orig_data_begin_ = orig_data_end_ = 0;
|
||||
MarkOrCopy();
|
||||
}
|
||||
|
||||
void FlowBuffer::MarkOrCopyLine()
|
||||
{
|
||||
switch ( linebreak_style_ )
|
||||
{
|
||||
case CR_OR_LF:
|
||||
MarkOrCopyLine_CR_OR_LF();
|
||||
break;
|
||||
case STRICT_CRLF:
|
||||
MarkOrCopyLine_STRICT_CRLF();
|
||||
break;
|
||||
default:
|
||||
BINPAC_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Finite state automaton for CR_OR_LF:
|
||||
(!--line is complete, *--add to buffer)
|
||||
|
||||
CR_OR_LF_0:
|
||||
CR: CR_OR_LF_1 !
|
||||
LF: CR_OR_LF_0 !
|
||||
.: CR_OR_LF_0 *
|
||||
|
||||
CR_OR_LF_1:
|
||||
CR: CR_OR_LF_1 !
|
||||
LF: CR_OR_LF_0
|
||||
.: CR_OR_LF_0 *
|
||||
*/
|
||||
|
||||
void FlowBuffer::MarkOrCopyLine_CR_OR_LF()
|
||||
{
|
||||
if ( state_ == CR_OR_LF_1 &&
|
||||
orig_data_begin_ < orig_data_end_ && *orig_data_begin_ == LF )
|
||||
{
|
||||
state_ = CR_OR_LF_0;
|
||||
++orig_data_begin_;
|
||||
}
|
||||
|
||||
const_byteptr data;
|
||||
for ( data = orig_data_begin_; data < orig_data_end_; ++data )
|
||||
{
|
||||
switch ( *data )
|
||||
{
|
||||
case CR:
|
||||
state_ = CR_OR_LF_1;
|
||||
goto found_end_of_line;
|
||||
|
||||
case LF:
|
||||
// state_ = CR_OR_LF_0;
|
||||
goto found_end_of_line;
|
||||
|
||||
default:
|
||||
// state_ = CR_OR_LF_0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AppendToBuffer(orig_data_begin_, orig_data_end_ - orig_data_begin_);
|
||||
return;
|
||||
|
||||
found_end_of_line:
|
||||
if ( buffer_n_ == 0 )
|
||||
{
|
||||
frame_length_ = data - orig_data_begin_;
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendToBuffer(orig_data_begin_, data + 1 - orig_data_begin_);
|
||||
// But eliminate the last CR or LF
|
||||
--buffer_n_;
|
||||
}
|
||||
message_complete_ = true;
|
||||
|
||||
#if DEBUG_FLOW_BUFFER
|
||||
fprintf(stderr, "%.6f Line complete: [%s]\n",
|
||||
network_time(),
|
||||
string((const char *) begin(), (const char *) end()).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Finite state automaton and STRICT_CRLF:
|
||||
(!--line is complete, *--add to buffer)
|
||||
|
||||
STRICT_CRLF_0:
|
||||
CR: STRICT_CRLF_1 *
|
||||
LF: STRICT_CRLF_0 *
|
||||
.: STRICT_CRLF_0 *
|
||||
|
||||
STRICT_CRLF_1:
|
||||
CR: STRICT_CRLF_1 *
|
||||
LF: STRICT_CRLF_0 ! (--buffer_n_)
|
||||
.: STRICT_CRLF_0 *
|
||||
*/
|
||||
|
||||
void FlowBuffer::MarkOrCopyLine_STRICT_CRLF()
|
||||
{
|
||||
const_byteptr data;
|
||||
for ( data = orig_data_begin_; data < orig_data_end_; ++data )
|
||||
{
|
||||
switch ( *data )
|
||||
{
|
||||
case CR:
|
||||
state_ = STRICT_CRLF_1;
|
||||
break;
|
||||
|
||||
case LF:
|
||||
if ( state_ == STRICT_CRLF_1 )
|
||||
{
|
||||
state_ = STRICT_CRLF_0;
|
||||
goto found_end_of_line;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
state_ = STRICT_CRLF_0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AppendToBuffer(orig_data_begin_, orig_data_end_ - orig_data_begin_);
|
||||
return;
|
||||
|
||||
found_end_of_line:
|
||||
if ( buffer_n_ == 0 )
|
||||
{
|
||||
frame_length_ = data - 1 - orig_data_begin_;
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendToBuffer(orig_data_begin_, data + 1 - orig_data_begin_);
|
||||
// Pop the preceding CR and LF from the buffer
|
||||
buffer_n_ -= 2;
|
||||
}
|
||||
|
||||
message_complete_ = true;
|
||||
|
||||
#if DEBUG_FLOW_BUFFER
|
||||
fprintf(stderr, "%.6f Line complete: [%s]\n",
|
||||
network_time(),
|
||||
string((const char *) begin(), (const char *) end()).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Invariants:
|
||||
//
|
||||
// When buffer_n_ == 0:
|
||||
// Frame = [orig_data_begin_..(orig_data_begin_ + frame_length_)]
|
||||
//
|
||||
// When buffer_n_ > 0:
|
||||
// Frame = [0..buffer_n_][orig_data_begin_..]
|
||||
|
||||
void FlowBuffer::MarkOrCopyFrame()
|
||||
{
|
||||
if ( mode_ == FRAME_MODE && state_ == CR_OR_LF_1 &&
|
||||
orig_data_begin_ < orig_data_end_ )
|
||||
{
|
||||
// Skip the lingering LF
|
||||
if ( *orig_data_begin_ == LF )
|
||||
{
|
||||
++orig_data_begin_;
|
||||
}
|
||||
state_ = FRAME_0;
|
||||
}
|
||||
|
||||
if ( buffer_n_ == 0 )
|
||||
{
|
||||
// If there is enough data
|
||||
if ( frame_length_ >= 0 &&
|
||||
orig_data_end_ - orig_data_begin_ >= frame_length_ )
|
||||
{
|
||||
// Do nothing except setting the message complete flag
|
||||
message_complete_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! chunked_ )
|
||||
{
|
||||
AppendToBuffer(orig_data_begin_,
|
||||
orig_data_end_ - orig_data_begin_);
|
||||
}
|
||||
message_complete_ = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BINPAC_ASSERT(!chunked_);
|
||||
int bytes_to_copy = orig_data_end_ - orig_data_begin_;
|
||||
message_complete_ = false;
|
||||
if ( frame_length_ >= 0 && buffer_n_ + bytes_to_copy >= frame_length_ )
|
||||
{
|
||||
bytes_to_copy = frame_length_ - buffer_n_;
|
||||
message_complete_ = true;
|
||||
}
|
||||
AppendToBuffer(orig_data_begin_, bytes_to_copy);
|
||||
}
|
||||
|
||||
#if DEBUG_FLOW_BUFFER
|
||||
if ( message_complete_ )
|
||||
{
|
||||
fprintf(stderr, "%.6f frame complete: [%s]\n",
|
||||
network_time(),
|
||||
string((const char *) begin(),
|
||||
(const char *) end()).c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlowBuffer::AppendToBuffer(const_byteptr data, int len)
|
||||
{
|
||||
if ( len <= 0 )
|
||||
return;
|
||||
|
||||
BINPAC_ASSERT(! chunked_);
|
||||
ExpandBuffer(buffer_n_ + len);
|
||||
memcpy(buffer_ + buffer_n_, data, len);
|
||||
buffer_n_ += len;
|
||||
|
||||
orig_data_begin_ += len;
|
||||
BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_);
|
||||
}
|
||||
|
||||
} // namespace binpac
|
|
@ -1,148 +0,0 @@
|
|||
#ifndef binpac_buffer_h
|
||||
#define binpac_buffer_h
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "binpac.h"
|
||||
|
||||
namespace binpac {
|
||||
|
||||
class FlowBuffer {
|
||||
public:
|
||||
enum LineBreakStyle {
|
||||
CR_OR_LF, // CR or LF or CRLF
|
||||
STRICT_CRLF, // CR followed by LF
|
||||
CR_LF_NUL, // CR or LF or CR-LF or CR-NUL
|
||||
};
|
||||
|
||||
FlowBuffer(LineBreakStyle linebreak_style = CR_OR_LF);
|
||||
virtual ~FlowBuffer();
|
||||
|
||||
void NewData(const_byteptr begin, const_byteptr end);
|
||||
void NewGap(int length);
|
||||
|
||||
// Discard unprocessed data
|
||||
void DiscardData();
|
||||
|
||||
// Whether there is enough data for the frame
|
||||
bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; }
|
||||
|
||||
inline const_byteptr begin() const
|
||||
{
|
||||
BINPAC_ASSERT(ready());
|
||||
return ( buffer_n_ == 0 ) ?
|
||||
orig_data_begin_ : buffer_;
|
||||
}
|
||||
|
||||
inline const_byteptr end() const
|
||||
{
|
||||
BINPAC_ASSERT(ready());
|
||||
if ( buffer_n_ == 0 )
|
||||
{
|
||||
BINPAC_ASSERT(frame_length_ >= 0);
|
||||
const_byteptr end = orig_data_begin_ + frame_length_;
|
||||
BINPAC_ASSERT(end <= orig_data_end_);
|
||||
return end;
|
||||
}
|
||||
else
|
||||
return buffer_ + buffer_n_;
|
||||
}
|
||||
|
||||
inline int data_length() const
|
||||
{
|
||||
if ( buffer_n_ > 0 )
|
||||
return buffer_n_;
|
||||
|
||||
if ( frame_length_ < 0 ||
|
||||
orig_data_begin_ + frame_length_ > orig_data_end_ )
|
||||
return orig_data_end_ - orig_data_begin_;
|
||||
else
|
||||
return frame_length_;
|
||||
}
|
||||
|
||||
inline bool data_available() const
|
||||
{
|
||||
return buffer_n_ > 0 || orig_data_end_ > orig_data_begin_;
|
||||
}
|
||||
|
||||
void NewLine();
|
||||
// A negative frame_length represents a frame till EOF
|
||||
void NewFrame(int frame_length, bool chunked_);
|
||||
void GrowFrame(int new_frame_length);
|
||||
|
||||
int data_seq() const
|
||||
{
|
||||
int data_seq_at_orig_data_begin =
|
||||
data_seq_at_orig_data_end_ -
|
||||
(orig_data_end_ - orig_data_begin_);
|
||||
if ( buffer_n_ > 0 )
|
||||
return data_seq_at_orig_data_begin;
|
||||
else
|
||||
return data_seq_at_orig_data_begin + data_length();
|
||||
}
|
||||
bool eof() const { return eof_; }
|
||||
void set_eof();
|
||||
|
||||
bool have_pending_request() const { return have_pending_request_; }
|
||||
|
||||
protected:
|
||||
// Reset the buffer for a new message
|
||||
void NewMessage();
|
||||
|
||||
void ClearPreviousData();
|
||||
|
||||
// Expand the buffer to at least <length> bytes. If there
|
||||
// are contents in the existing buffer, copy them to the new
|
||||
// buffer.
|
||||
void ExpandBuffer(int length);
|
||||
|
||||
// Reset line state when transit from frame mode to line mode.
|
||||
void ResetLineState();
|
||||
|
||||
void AppendToBuffer(const_byteptr data, int len);
|
||||
|
||||
// MarkOrCopy{Line,Frame} sets message_complete_ and
|
||||
// marks begin/end pointers if a line/frame is complete,
|
||||
// otherwise it clears message_complete_ and copies all
|
||||
// the original data to the buffer.
|
||||
//
|
||||
void MarkOrCopy();
|
||||
void MarkOrCopyLine();
|
||||
void MarkOrCopyFrame();
|
||||
|
||||
void MarkOrCopyLine_CR_OR_LF();
|
||||
void MarkOrCopyLine_STRICT_CRLF();
|
||||
|
||||
int buffer_n_; // number of bytes in the buffer
|
||||
int buffer_length_; // size of the buffer
|
||||
u_char *buffer_;
|
||||
bool message_complete_;
|
||||
int frame_length_;
|
||||
bool chunked_;
|
||||
const_byteptr orig_data_begin_, orig_data_end_;
|
||||
|
||||
LineBreakStyle linebreak_style_;
|
||||
|
||||
enum {
|
||||
UNKNOWN_MODE,
|
||||
LINE_MODE,
|
||||
FRAME_MODE,
|
||||
} mode_;
|
||||
|
||||
enum {
|
||||
CR_OR_LF_0,
|
||||
CR_OR_LF_1,
|
||||
STRICT_CRLF_0,
|
||||
STRICT_CRLF_1,
|
||||
FRAME_0,
|
||||
} state_;
|
||||
|
||||
int data_seq_at_orig_data_end_;
|
||||
bool eof_;
|
||||
bool have_pending_request_;
|
||||
};
|
||||
|
||||
typedef FlowBuffer *flow_buffer_t;
|
||||
|
||||
} // namespace binpac
|
||||
|
||||
#endif // binpac_buffer_h
|
|
@ -1,24 +0,0 @@
|
|||
#define binpac_regex_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "binpac_bytestring.h"
|
||||
|
||||
namespace binpac
|
||||
{
|
||||
|
||||
std::string std_string(bytestring const *s)
|
||||
{
|
||||
return std::string((const char *) s->begin(), (const char *) s->end());
|
||||
}
|
||||
|
||||
int bytestring_to_int(bytestring const *s)
|
||||
{
|
||||
return atoi((const char *) s->begin());
|
||||
}
|
||||
|
||||
double bytestring_to_double(bytestring const *s)
|
||||
{
|
||||
return atof((const char *) s->begin());
|
||||
}
|
||||
|
||||
} // namespace binpac
|
|
@ -1,199 +0,0 @@
|
|||
#ifndef binpac_bytestring_h
|
||||
#define binpac_bytestring_h
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "binpac.h"
|
||||
|
||||
namespace binpac
|
||||
{
|
||||
|
||||
template<class T> class datastring;
|
||||
|
||||
template <class T>
|
||||
class const_datastring
|
||||
{
|
||||
public:
|
||||
const_datastring()
|
||||
: begin_(0), end_(0)
|
||||
{
|
||||
}
|
||||
|
||||
const_datastring(T const *data, int length)
|
||||
: begin_(data), end_(data + length)
|
||||
{
|
||||
}
|
||||
|
||||
const_datastring(const T *begin, const T *end)
|
||||
: begin_(begin), end_(end)
|
||||
{
|
||||
}
|
||||
|
||||
const_datastring(datastring<T> const &s)
|
||||
: begin_(s.begin()), end_(s.end())
|
||||
{
|
||||
}
|
||||
|
||||
void init(const T *data, int length)
|
||||
{
|
||||
begin_ = data;
|
||||
end_ = data + length;
|
||||
}
|
||||
|
||||
T const *begin() const { return begin_; }
|
||||
T const *end() const { return end_; }
|
||||
int length() const { return end_ - begin_; }
|
||||
|
||||
T const &operator[](int index) const
|
||||
{
|
||||
return begin()[index];
|
||||
}
|
||||
|
||||
bool operator==(const_datastring<T> const &s)
|
||||
{
|
||||
if ( length() != s.length() )
|
||||
return false;
|
||||
return memcmp((const void *) begin(), (const void *) s.begin(),
|
||||
sizeof(T) * length()) == 0;
|
||||
}
|
||||
|
||||
void set_begin(T const *begin) { begin_ = begin; }
|
||||
void set_end(T const *end) { end_ = end; }
|
||||
|
||||
private:
|
||||
T const *begin_;
|
||||
T const *end_;
|
||||
};
|
||||
|
||||
typedef const_datastring<uint8> const_bytestring;
|
||||
|
||||
template<class T>
|
||||
class datastring
|
||||
{
|
||||
public:
|
||||
datastring()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
datastring(T *data, int len)
|
||||
{
|
||||
set(data, len);
|
||||
}
|
||||
|
||||
datastring(T const *begin, T const *end)
|
||||
{
|
||||
set_const(begin, end - begin);
|
||||
}
|
||||
|
||||
datastring(datastring<T> const &x)
|
||||
: data_(x.data()), length_(x.length())
|
||||
{
|
||||
}
|
||||
|
||||
explicit datastring(const_datastring<T> const &x)
|
||||
{
|
||||
set_const(x.begin(), x.length());
|
||||
}
|
||||
|
||||
datastring const &operator=(datastring<T> const &x)
|
||||
{
|
||||
BINPAC_ASSERT(!data_);
|
||||
set(x.data(), x.length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void init(T const *begin, int length)
|
||||
{
|
||||
BINPAC_ASSERT(!data_);
|
||||
set_const(begin, length);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data_ = 0; length_ = 0;
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
if ( data_ )
|
||||
delete [] data_;
|
||||
clear();
|
||||
}
|
||||
|
||||
void clone()
|
||||
{
|
||||
set_const(begin(), length());
|
||||
}
|
||||
|
||||
datastring const &operator=(const_datastring<T> const &x)
|
||||
{
|
||||
BINPAC_ASSERT(!data_);
|
||||
set_const(x.begin(), x.length());
|
||||
return *this;
|
||||
}
|
||||
|
||||
T const &operator[](int index) const
|
||||
{
|
||||
return begin()[index];
|
||||
}
|
||||
|
||||
T *data() const { return data_; }
|
||||
int length() const { return length_; }
|
||||
|
||||
T const *begin() const { return data_; }
|
||||
T const *end() const { return data_ + length_; }
|
||||
|
||||
private:
|
||||
void set(T *data, int len)
|
||||
{
|
||||
data_ = data;
|
||||
length_ = len;
|
||||
}
|
||||
|
||||
void set_const(T const *data, int len)
|
||||
{
|
||||
length_ = len;
|
||||
data_ = new T[len + 1];
|
||||
memcpy(data_, data, sizeof(T) * len);
|
||||
data_[len] = 0;
|
||||
}
|
||||
|
||||
T * data_;
|
||||
int length_;
|
||||
};
|
||||
|
||||
typedef datastring<uint8> bytestring;
|
||||
|
||||
inline const char *c_str(bytestring const &s)
|
||||
{
|
||||
return (const char *) s.begin();
|
||||
}
|
||||
|
||||
inline std::string std_str(const_bytestring const &s)
|
||||
{
|
||||
return std::string((const char *) s.begin(), (const char *) s.end());
|
||||
}
|
||||
|
||||
inline bool operator==(bytestring const &s1, const char *s2)
|
||||
{
|
||||
return strcmp(c_str(s1), s2) == 0;
|
||||
}
|
||||
|
||||
inline void get_pointers(const_bytestring const &s,
|
||||
uint8 const **pbegin, uint8 const **pend)
|
||||
{
|
||||
*pbegin = s.begin();
|
||||
*pend = s.end();
|
||||
}
|
||||
|
||||
inline void get_pointers(bytestring const *s,
|
||||
uint8 const **pbegin, uint8 const **pend)
|
||||
{
|
||||
*pbegin = s->begin();
|
||||
*pend = s->end();
|
||||
}
|
||||
|
||||
} // namespace binpac
|
||||
|
||||
#endif // binpac_bytestring_h
|
|
@ -1,112 +0,0 @@
|
|||
#ifndef binpac_exception_h
|
||||
#define binpac_exception_h
|
||||
|
||||
namespace binpac {
|
||||
|
||||
class Exception
|
||||
{
|
||||
public:
|
||||
Exception(const char* m = 0)
|
||||
: msg_("binpac exception: ")
|
||||
{
|
||||
if ( m )
|
||||
append(m);
|
||||
// abort();
|
||||
}
|
||||
|
||||
void append(string m) { msg_ += m; }
|
||||
string msg() const { return msg_; }
|
||||
const char* c_msg() const { return msg().c_str(); }
|
||||
|
||||
protected:
|
||||
string msg_;
|
||||
};
|
||||
|
||||
class ExceptionOutOfBound : public Exception
|
||||
{
|
||||
public:
|
||||
ExceptionOutOfBound(const char* where, int len_needed, int len_given)
|
||||
{
|
||||
append(binpac_fmt("out_of_bound: %s: %d > %d",
|
||||
where, len_needed, len_given));
|
||||
}
|
||||
};
|
||||
|
||||
class ExceptionInvalidCase : public Exception
|
||||
{
|
||||
public:
|
||||
ExceptionInvalidCase(const char* location,
|
||||
int index,
|
||||
const char *expected)
|
||||
: location_(location),
|
||||
index_(index),
|
||||
expected_(expected)
|
||||
{
|
||||
append(binpac_fmt("invalid case: %s: %d (%s)",
|
||||
location, index, expected));
|
||||
}
|
||||
|
||||
protected:
|
||||
const char* location_;
|
||||
int index_;
|
||||
string expected_;
|
||||
};
|
||||
|
||||
class ExceptionInvalidCaseIndex : public Exception
|
||||
{
|
||||
public:
|
||||
ExceptionInvalidCaseIndex(const char* location,
|
||||
int index)
|
||||
: location_(location),
|
||||
index_(index)
|
||||
{
|
||||
append(binpac_fmt("invalid index for case: %s: %d",
|
||||
location, index));
|
||||
}
|
||||
|
||||
protected:
|
||||
const char* location_;
|
||||
int index_;
|
||||
};
|
||||
|
||||
class ExceptionInvalidOffset : public Exception
|
||||
{
|
||||
public:
|
||||
ExceptionInvalidOffset(const char* location,
|
||||
int min_offset, int offset)
|
||||
: location_(location),
|
||||
min_offset_(min_offset), offset_(offset)
|
||||
{
|
||||
append(binpac_fmt("invalid offset: %s: min_offset = %d, offset = %d",
|
||||
location, min_offset, offset));
|
||||
}
|
||||
|
||||
protected:
|
||||
const char* location_;
|
||||
int min_offset_, offset_;
|
||||
};
|
||||
|
||||
class ExceptionStringMismatch : public Exception
|
||||
{
|
||||
public:
|
||||
ExceptionStringMismatch(const char* location,
|
||||
const char *expected, const char *actual_data)
|
||||
{
|
||||
append(binpac_fmt("string mismatch at %s: \nexpected pattern: \"%s\"\nactual data: \"%s\"",
|
||||
location, expected, actual_data));
|
||||
}
|
||||
};
|
||||
|
||||
class ExceptionInvalidStringLength : public Exception
|
||||
{
|
||||
public:
|
||||
ExceptionInvalidStringLength(const char* location, int len)
|
||||
{
|
||||
append(binpac_fmt("invalid length string: %s: %d",
|
||||
location, len));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // binpac_exception_h
|
|
@ -1,43 +0,0 @@
|
|||
#ifndef binpac_regex_h
|
||||
#define binpac_regex_h
|
||||
|
||||
#include "binpac.h"
|
||||
#include "RE.h"
|
||||
|
||||
class RE_Matcher;
|
||||
|
||||
namespace binpac
|
||||
{
|
||||
|
||||
class RegExMatcher {
|
||||
public:
|
||||
RegExMatcher(const char *pattern)
|
||||
: pattern_(pattern)
|
||||
{
|
||||
re_matcher_ = 0;
|
||||
}
|
||||
|
||||
~RegExMatcher()
|
||||
{
|
||||
delete re_matcher_;
|
||||
}
|
||||
|
||||
// Returns the length of longest match, or -1 on mismatch.
|
||||
int MatchPrefix(const_byteptr data, int len)
|
||||
{
|
||||
if ( ! re_matcher_ )
|
||||
{
|
||||
re_matcher_ = new RE_Matcher(pattern_.c_str());
|
||||
re_matcher_->Compile();
|
||||
}
|
||||
return re_matcher_->MatchPrefix(data, len);
|
||||
}
|
||||
|
||||
private:
|
||||
string pattern_;
|
||||
RE_Matcher *re_matcher_;
|
||||
};
|
||||
|
||||
} // namespace binpac
|
||||
|
||||
#endif // binpac_regex_h
|
|
@ -1,31 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_expr.cc bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_expr.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc 2007-05-04 14:31:11.728494000 -0700
|
||||
@@ -776,6 +776,27 @@
|
||||
}
|
||||
break;
|
||||
|
||||
+ case EXPR_CALLARGS:
|
||||
+ {
|
||||
+ mhs = 0;
|
||||
+ if ( args_ )
|
||||
+ for ( uint i = 0; i < args_->size(); ++i )
|
||||
+ mhs = mhs_max(mhs, args_->at(i)->MinimalHeaderSize(env));
|
||||
+ }
|
||||
+ break;
|
||||
+ case EXPR_CASE:
|
||||
+ {
|
||||
+ mhs = operand_[0]->MinimalHeaderSize(env);
|
||||
+ for ( uint i = 0; i < cases_->size(); ++i )
|
||||
+ {
|
||||
+ CaseExpr * ce = cases_->at(i);
|
||||
+ if ( ce->index() )
|
||||
+ for ( uint j = 0; j < ce->index()->size(); ++j )
|
||||
+ mhs = mhs_max(mhs, ce->index()->at(j)->MinimalHeaderSize(env));
|
||||
+ mhs = mhs_max(mhs, ce->value()->MinimalHeaderSize(env));
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
default:
|
||||
// Evaluate every operand by default
|
||||
mhs = 0;
|
|
@ -1,97 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_expr.cc bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_expr.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc 2007-05-04 14:31:11.728494000 -0700
|
||||
@@ -245,6 +245,12 @@
|
||||
out_cc->println("%s %s;",
|
||||
val_type->DataTypeStr().c_str(),
|
||||
env->LValue(val_var));
|
||||
+
|
||||
+ // force evaluation of IDs appearing in case stmt
|
||||
+ operand_[0]->ForceIDEval(out_cc, env);
|
||||
+ foreach(i, CaseExprList, cases_)
|
||||
+ (*i)->value()->ForceIDEval(out_cc, env);
|
||||
+
|
||||
out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env));
|
||||
|
||||
out_cc->inc_indent();
|
||||
@@ -386,6 +392,49 @@
|
||||
}
|
||||
}
|
||||
|
||||
+void Expr::ForceIDEval(Output* out_cc, Env* env)
|
||||
+ {
|
||||
+ switch ( expr_type_ )
|
||||
+ {
|
||||
+ case EXPR_NUM:
|
||||
+ case EXPR_SIZEOF:
|
||||
+ case EXPR_OFFSETOF:
|
||||
+ break;
|
||||
+
|
||||
+ case EXPR_ID:
|
||||
+ if ( ! env->Evaluated(id_) )
|
||||
+ env->Evaluate(out_cc, id_);
|
||||
+ break;
|
||||
+
|
||||
+ case EXPR_MEMBER:
|
||||
+ operand_[0]->ForceIDEval(out_cc, env);
|
||||
+ break;
|
||||
+
|
||||
+ case EXPR_CALLARGS:
|
||||
+ {
|
||||
+ foreach(i, ExprList, args_)
|
||||
+ (*i)->ForceIDEval(out_cc, env);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case EXPR_CASE:
|
||||
+ {
|
||||
+ operand_[0]->ForceIDEval(out_cc, env);
|
||||
+ foreach(i, CaseExprList, cases_)
|
||||
+ (*i)->value()->ForceIDEval(out_cc, env);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ // Evaluate every operand by default
|
||||
+ for ( int i = 0; i < 3; ++i )
|
||||
+ if ( operand_[i] )
|
||||
+ operand_[i]->ForceIDEval(out_cc, env);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
const char* Expr::EvalExpr(Output* out_cc, Env* env)
|
||||
{
|
||||
GenEval(out_cc, env);
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_expr.h bro-1.2.1-ssl-binpac/src/binpac/pac_expr.h
|
||||
--- bro-1.2.1-orig/src/binpac/pac_expr.h 2006-07-26 15:02:39.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_expr.h 2007-05-04 14:16:31.624287000 -0700
|
||||
@@ -56,6 +56,11 @@
|
||||
//
|
||||
const char *EvalExpr(Output *out, Env *env);
|
||||
|
||||
+ // force evaulation of IDs contained in this expression;
|
||||
+ // necessary with case expr and conditional let fields (&if)
|
||||
+ // for correct parsing of fields
|
||||
+ void ForceIDEval(Output *out_cc, Env *env);
|
||||
+
|
||||
// Returns the set_* function of the expression.
|
||||
// The expression must be of form ID or x.ID.
|
||||
string SetFunc(Output *out, Env *env);
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_let.cc bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_let.cc 2006-07-26 15:02:39.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc 2007-05-04 15:32:09.695568000 -0700
|
||||
@@ -80,7 +80,12 @@
|
||||
if ( type_->attr_if_expr() )
|
||||
{
|
||||
// A conditional field
|
||||
+
|
||||
env->Evaluate(out_cc, type_->has_value_var());
|
||||
+
|
||||
+ // force evaluation of IDs contained in this expr
|
||||
+ expr()->ForceIDEval(out_cc, env);
|
||||
+
|
||||
out_cc->println("if ( %s )",
|
||||
env->RValue(type_->has_value_var()));
|
||||
out_cc->inc_indent();
|
|
@ -1,37 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_let.cc bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_let.cc 2006-07-26 15:02:39.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc 2007-05-04 15:32:09.695568000 -0700
|
||||
@@ -108,11 +108,6 @@
|
||||
void LetField::GenEval(Output* out_cc, Env* env)
|
||||
{
|
||||
GenParseCode(out_cc, env);
|
||||
- if ( type_->attr_if_expr() )
|
||||
- {
|
||||
- out_cc->println("BINPAC_ASSERT(%s);",
|
||||
- env->RValue(type_->has_value_var()));
|
||||
- }
|
||||
}
|
||||
|
||||
LetDecl::LetDecl(ID *id, Type *type, Expr *expr)
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_type.cc bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_type.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc 2007-05-24 10:56:42.140658000 -0700
|
||||
@@ -316,9 +316,15 @@
|
||||
{
|
||||
if ( DefineValueVar() )
|
||||
{
|
||||
- out_h->println("%s %s const { return %s; }",
|
||||
- DataTypeConstRefStr().c_str(),
|
||||
- env->RValue(value_var()), lvalue());
|
||||
+ if ( attr_if_expr_ )
|
||||
+ out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }",
|
||||
+ DataTypeConstRefStr().c_str(),
|
||||
+ env->RValue(value_var()),
|
||||
+ env->RValue(has_value_var()), lvalue());
|
||||
+ else
|
||||
+ out_h->println("%s %s const { return %s; }",
|
||||
+ DataTypeConstRefStr().c_str(),
|
||||
+ env->RValue(value_var()), lvalue());
|
||||
}
|
||||
|
||||
foreach (i, FieldList, fields_)
|
|
@ -1,12 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_record.cc bro-1.2.1-ssl-binpac/src/binpac/pac_record.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_record.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_record.cc 2007-05-08 16:13:33.373850000 -0700
|
||||
@@ -123,7 +123,7 @@
|
||||
void RecordType::DoGenParseCode(Output* out_cc, Env* env,
|
||||
const DataPtr& data, int flags)
|
||||
{
|
||||
- if ( StaticSize(env) >= 0 )
|
||||
+ if ( !incremental_input() && StaticSize(env) >= 0 )
|
||||
GenBoundaryCheck(out_cc, env, data);
|
||||
|
||||
if ( incremental_parsing() )
|
|
@ -1,66 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_paramtype.cc bro-1.2.1-ssl-binpac/src/binpac/pac_paramtype.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_paramtype.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_paramtype.cc 2007-05-10 15:09:47.470104000 -0700
|
||||
@@ -208,7 +208,13 @@
|
||||
const char *parse_func;
|
||||
string parse_params;
|
||||
|
||||
- if ( ref_type->incremental_input() )
|
||||
+ if ( buffer_mode() == BUFFER_NOTHING )
|
||||
+ {
|
||||
+ ASSERT(!ref_type->incremental_input());
|
||||
+ parse_func = kParseFuncWithoutBuffer;
|
||||
+ parse_params = "0, 0";
|
||||
+ }
|
||||
+ else if ( ref_type->incremental_input() )
|
||||
{
|
||||
parse_func = kParseFuncWithBuffer;
|
||||
parse_params = env->RValue(flow_buffer_id);
|
||||
@@ -239,15 +245,24 @@
|
||||
|
||||
if ( incremental_input() )
|
||||
{
|
||||
- ASSERT(parsing_complete_var());
|
||||
- out_cc->println("%s = %s;",
|
||||
- env->LValue(parsing_complete_var()),
|
||||
- call_parse_func.c_str());
|
||||
-
|
||||
- // parsing_complete_var might have been already
|
||||
- // evaluated when set to false
|
||||
- if ( ! env->Evaluated(parsing_complete_var()) )
|
||||
- env->SetEvaluated(parsing_complete_var());
|
||||
+ if ( buffer_mode() == BUFFER_NOTHING )
|
||||
+ {
|
||||
+ out_cc->println("%s;", call_parse_func.c_str());
|
||||
+ out_cc->println("%s = true;",
|
||||
+ env->LValue(parsing_complete_var()));
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ASSERT(parsing_complete_var());
|
||||
+ out_cc->println("%s = %s;",
|
||||
+ env->LValue(parsing_complete_var()),
|
||||
+ call_parse_func.c_str());
|
||||
+
|
||||
+ // parsing_complete_var might have been already
|
||||
+ // evaluated when set to false
|
||||
+ if ( ! env->Evaluated(parsing_complete_var()) )
|
||||
+ env->SetEvaluated(parsing_complete_var());
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_type.cc bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_type.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc 2007-05-24 10:56:42.140658000 -0700
|
||||
@@ -501,8 +501,8 @@
|
||||
|
||||
if ( buffer_mode() == BUFFER_NOTHING )
|
||||
{
|
||||
- out_cc->println("%s = true;",
|
||||
- env->LValue(parsing_complete_var()));
|
||||
+ // this is the empty type
|
||||
+ DoGenParseCode(out_cc, env, data, flags);
|
||||
}
|
||||
else if ( buffer_input() )
|
||||
{
|
|
@ -1,28 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/lib/binpac_buffer.h bro-1.2.1-ssl-binpac/src/binpac/lib/binpac_buffer.h
|
||||
--- bro-1.2.1-orig/src/binpac/lib/binpac_buffer.h 2006-07-26 15:02:38.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/lib/binpac_buffer.h 2007-05-09 16:14:54.501656000 -0700
|
||||
@@ -59,6 +59,11 @@
|
||||
return frame_length_;
|
||||
}
|
||||
|
||||
+ inline bool data_available() const
|
||||
+ {
|
||||
+ return buffer_n_ > 0 || orig_data_end_ > orig_data_begin_;
|
||||
+ }
|
||||
+
|
||||
void NewLine();
|
||||
// A negative frame_length represents a frame till EOF
|
||||
void NewFrame(int frame_length, bool chunked_);
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_flow.cc bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_flow.cc 2006-10-12 14:13:12.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc 2007-05-22 16:43:55.997562000 -0700
|
||||
@@ -272,7 +272,8 @@
|
||||
env_->RValue(begin_of_data),
|
||||
env_->RValue(end_of_data));
|
||||
|
||||
- out_cc->println("while ( true )");
|
||||
+ out_cc->println("while ( %s->data_available() )",
|
||||
+ env_->LValue(flow_buffer_id));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_type.cc bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_type.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc 2007-05-24 10:56:42.140658000 -0700
|
||||
@@ -393,7 +393,7 @@
|
||||
break;
|
||||
|
||||
case BUFFER_BY_LENGTH:
|
||||
- if ( buffering_state_var_field_ )
|
||||
+ if ( env->GetDataType(buffering_state_id) )
|
||||
{
|
||||
out_cc->println("if ( %s == 0 )",
|
||||
env->RValue(buffering_state_id));
|
||||
@@ -421,7 +421,7 @@
|
||||
frame_buffer_arg.c_str(),
|
||||
attr_chunked() ? "true" : "false");
|
||||
|
||||
- if ( buffering_state_var_field_ )
|
||||
+ if ( env->GetDataType(buffering_state_id) )
|
||||
{
|
||||
out_cc->println("%s = 1;",
|
||||
env->LValue(buffering_state_id));
|
|
@ -1,190 +0,0 @@
|
|||
diff -urN bro-1.2.1-orig/src/binpac/pac_analyzer.cc bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_analyzer.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.cc 2007-05-22 17:00:10.091531000 -0700
|
||||
@@ -26,8 +26,9 @@
|
||||
helpers_ = new AnalyzerHelperList();
|
||||
functions_ = new FunctionList();
|
||||
|
||||
- constructor_helper_ = 0;
|
||||
- destructor_helper_ = 0;
|
||||
+ constructor_helpers_ = new AnalyzerHelperList();
|
||||
+ destructor_helpers_ = new AnalyzerHelperList();
|
||||
+ eof_helpers_ = new AnalyzerHelperList();
|
||||
|
||||
SetAnalyzerContext();
|
||||
|
||||
@@ -41,6 +42,9 @@
|
||||
delete_list(AnalyzerHelperList, helpers_);
|
||||
delete_list(FunctionList, functions_);
|
||||
delete_list(ParamList, params_);
|
||||
+ delete_list(AnalyzerHelperList, constructor_helpers_);
|
||||
+ delete_list(AnalyzerHelperList, destructor_helpers_);
|
||||
+ delete_list(AnalyzerHelperList, eof_helpers_);
|
||||
}
|
||||
|
||||
void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
|
||||
@@ -75,28 +79,20 @@
|
||||
AnalyzerHelper *helper_elem =
|
||||
(AnalyzerHelper *) elem;
|
||||
|
||||
- if ( helper_elem->helper_type() ==
|
||||
- AnalyzerHelper::INIT_CODE)
|
||||
- {
|
||||
- if ( constructor_helper_ )
|
||||
- {
|
||||
- throw Exception(elem,
|
||||
- "Repeated definition of %init code");
|
||||
- }
|
||||
- constructor_helper_ = helper_elem;
|
||||
+ switch ( helper_elem->helper_type() )
|
||||
+ {
|
||||
+ case AnalyzerHelper::INIT_CODE:
|
||||
+ constructor_helpers_->push_back(helper_elem);
|
||||
+ break;
|
||||
+ case AnalyzerHelper::CLEANUP_CODE:
|
||||
+ destructor_helpers_->push_back(helper_elem);
|
||||
+ break;
|
||||
+ case AnalyzerHelper::EOF_CODE:
|
||||
+ eof_helpers_->push_back(helper_elem);
|
||||
+ break;
|
||||
+ default:
|
||||
+ helpers_->push_back(helper_elem);
|
||||
}
|
||||
- else if ( helper_elem->helper_type() ==
|
||||
- AnalyzerHelper::CLEANUP_CODE)
|
||||
- {
|
||||
- if ( destructor_helper_ )
|
||||
- {
|
||||
- throw Exception(elem,
|
||||
- "Repeated definition of %cleanup code");
|
||||
- }
|
||||
- destructor_helper_ = helper_elem;
|
||||
- }
|
||||
- else
|
||||
- helpers_->push_back(helper_elem);
|
||||
}
|
||||
break;
|
||||
case AnalyzerElement::FUNCTION:
|
||||
@@ -217,15 +213,19 @@
|
||||
void AnalyzerDecl::GenInitCode(Output *out_cc)
|
||||
{
|
||||
TypeDecl::GenInitCode(out_cc);
|
||||
- if ( constructor_helper_ )
|
||||
- constructor_helper_->GenCode(0, out_cc, this);
|
||||
+ foreach(i, AnalyzerHelperList, constructor_helpers_)
|
||||
+ {
|
||||
+ (*i)->GenCode(0, out_cc, this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenCleanUpCode(Output *out_cc)
|
||||
{
|
||||
TypeDecl::GenCleanUpCode(out_cc);
|
||||
- if ( destructor_helper_ )
|
||||
- destructor_helper_->GenCode(0, out_cc, this);
|
||||
+ foreach(i, AnalyzerHelperList, destructor_helpers_)
|
||||
+ {
|
||||
+ (*i)->GenCode(0, out_cc, this);
|
||||
+ }
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenStateVarDecls(Output *out_h)
|
||||
@@ -295,6 +295,7 @@
|
||||
break;
|
||||
case INIT_CODE:
|
||||
case CLEANUP_CODE:
|
||||
+ case EOF_CODE:
|
||||
out = out_cc;
|
||||
break;
|
||||
}
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_analyzer.h bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.h
|
||||
--- bro-1.2.1-orig/src/binpac/pac_analyzer.h 2006-07-26 15:02:39.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.h 2007-05-22 16:32:08.397926000 -0700
|
||||
@@ -76,8 +76,9 @@
|
||||
AnalyzerHelperList *helpers_;
|
||||
FunctionList *functions_;
|
||||
|
||||
- AnalyzerHelper *constructor_helper_;
|
||||
- AnalyzerHelper *destructor_helper_;
|
||||
+ AnalyzerHelperList *constructor_helpers_;
|
||||
+ AnalyzerHelperList *destructor_helpers_;
|
||||
+ AnalyzerHelperList *eof_helpers_;
|
||||
};
|
||||
|
||||
class AnalyzerElement : public Object
|
||||
@@ -117,6 +118,7 @@
|
||||
MEMBER_DECLS,
|
||||
INIT_CODE,
|
||||
CLEANUP_CODE,
|
||||
+ EOF_CODE,
|
||||
};
|
||||
AnalyzerHelper(Type helper_type, EmbeddedCode *code)
|
||||
: AnalyzerElement(HELPER),
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_conn.cc bro-1.2.1-ssl-binpac/src/binpac/pac_conn.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_conn.cc 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_conn.cc 2007-05-22 16:42:35.406135000 -0700
|
||||
@@ -97,6 +97,12 @@
|
||||
out_cc->println("%s->%s();",
|
||||
env_->LValue(downflow_id),
|
||||
kFlowEOF);
|
||||
+
|
||||
+ foreach(i, AnalyzerHelperList, eof_helpers_)
|
||||
+ {
|
||||
+ (*i)->GenCode(0, out_cc, this);
|
||||
+ }
|
||||
+
|
||||
out_cc->dec_indent();
|
||||
|
||||
out_cc->println("}");
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_flow.cc bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc
|
||||
--- bro-1.2.1-orig/src/binpac/pac_flow.cc 2006-10-12 14:13:12.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc 2007-05-22 16:43:55.997562000 -0700
|
||||
@@ -151,6 +151,11 @@
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
+ foreach(i, AnalyzerHelperList, eof_helpers_)
|
||||
+ {
|
||||
+ (*i)->GenCode(0, out_cc, this);
|
||||
+ }
|
||||
+
|
||||
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
|
||||
{
|
||||
out_cc->println("%s->set_eof();",
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_parse.yy bro-1.2.1-ssl-binpac/src/binpac/pac_parse.yy
|
||||
--- bro-1.2.1-orig/src/binpac/pac_parse.yy 2006-10-12 14:13:12.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_parse.yy 2007-05-22 16:56:09.280526000 -0700
|
||||
@@ -22,7 +22,7 @@
|
||||
%token TOK_STATE TOK_ACTION TOK_WHEN TOK_HELPER
|
||||
%token TOK_DATAUNIT TOK_FLOWDIR TOK_WITHCONTEXT
|
||||
%token TOK_LPB_EXTERN TOK_LPB_HEADER TOK_LPB_CODE
|
||||
-%token TOK_LPB_MEMBER TOK_LPB_INIT TOK_LPB_CLEANUP
|
||||
+%token TOK_LPB_MEMBER TOK_LPB_INIT TOK_LPB_CLEANUP TOK_LPB_EOF
|
||||
%token TOK_LPB TOK_RPB
|
||||
%token TOK_EMBEDDED_ATOM TOK_EMBEDDED_STRING
|
||||
%token TOK_PAC_VAL TOK_PAC_SET TOK_PAC_TYPE TOK_PAC_TYPEOF TOK_PAC_CONST_DEF
|
||||
@@ -795,6 +795,10 @@
|
||||
{
|
||||
$$ = new AnalyzerHelper(AnalyzerHelper::CLEANUP_CODE, $2);
|
||||
}
|
||||
+ | TOK_LPB_EOF embedded_code TOK_RPB
|
||||
+ {
|
||||
+ $$ = new AnalyzerHelper(AnalyzerHelper::EOF_CODE, $2);
|
||||
+ }
|
||||
| TOK_FLOWDIR '=' tok_id optargs ';'
|
||||
{
|
||||
$$ = new AnalyzerFlow((AnalyzerFlow::Direction) $1, $3, $4);
|
||||
diff -urN bro-1.2.1-orig/src/binpac/pac_scan.ll bro-1.2.1-ssl-binpac/src/binpac/pac_scan.ll
|
||||
--- bro-1.2.1-orig/src/binpac/pac_scan.ll 2006-07-26 15:02:40.000000000 -0700
|
||||
+++ bro-1.2.1-ssl-binpac/src/binpac/pac_scan.ll 2007-05-22 16:55:19.349644000 -0700
|
||||
@@ -96,6 +96,10 @@
|
||||
BEGIN(EC);
|
||||
return TOK_LPB_MEMBER;
|
||||
}
|
||||
+<INITIAL>"%eof{" {
|
||||
+ BEGIN(EC);
|
||||
+ return TOK_LPB_EOF;
|
||||
+ }
|
||||
<INITIAL>"%{" {
|
||||
BEGIN(EC);
|
||||
return TOK_LPB;
|
|
@ -1,87 +0,0 @@
|
|||
binpac fixes
|
||||
----------------
|
||||
|
||||
numbers of issues below correspond to the patch numbers
|
||||
|
||||
(1) correct calculation of minimal header size in pac_expr.cc
|
||||
- problem: EXPR_CALLARGS and EXPR_CASE not considered for the calculation
|
||||
of minimal header size
|
||||
- solution: added two cases in switch stmt of Expr::MinimalHeaderSize
|
||||
for EXPR_CALLARGS and EXPR_CASE
|
||||
|
||||
|
||||
(2) ensure parsing of fields first referenced in a case expression or
|
||||
let field with an &if attribute
|
||||
- problem: in cases where the if expression evaluates to false or the
|
||||
proper case does not occur, fields get not parsed at all
|
||||
- solution: force evaluation of all IDs referenced in a let field with
|
||||
if attribute or a case expression before the body of the corresponding
|
||||
switch stmt or the if stmt
|
||||
- added public method Expr::ForceIDEval, properly called before
|
||||
generating the code of a field with if attribute or the case expression
|
||||
|
||||
|
||||
(3) properly assert the use of fields with an if attribute
|
||||
- problem: the use of fields with an if attribute was not asserted in all
|
||||
cases and asserted in the wrong way in some others due to the
|
||||
corresponding BINPAC_ASSERT only called upon parsing the field
|
||||
- solution: perform BINPAC_ASSERT upon calling the fields accessor
|
||||
function
|
||||
- moved BINPAC_ASSERT statement from LetField::GenEval to
|
||||
Type::GenPubDecls
|
||||
|
||||
|
||||
(4) incremental input with records with a non-negative StaticSize
|
||||
- problem: incremental input with records with a StaticSize >= 0
|
||||
cannot be performed due to necessary length attribute, leading to
|
||||
an invalid call of GenBoundaryCheck in RecordType::DoGenParseCode
|
||||
- solution: added a check for incremental input in
|
||||
RecordType::DoGenParseCode before calling GenBoundaryCheck
|
||||
|
||||
|
||||
(5) empty type with incremental input
|
||||
- problem: with an empty type and incremental input, although the
|
||||
Parse function is created, it is never called, leading to problems,
|
||||
if additional actions are to be performed when encountering that
|
||||
empty type
|
||||
- solution: generate call to Parse of empty type in Type::GenParseBuffer
|
||||
|
||||
|
||||
(6) parsing loop in flow ParseBuffer (while(true))
|
||||
- problem: while(true) leads to problems after parsing of a type is
|
||||
complete; at this time, it is unexpected that parsing continues, even
|
||||
if no data is available in the flow buffer
|
||||
- solution: check if data is available before starting a new parsing
|
||||
cycle
|
||||
- added a method data_available to FlowBuffer
|
||||
- changed while(true) in FlowDecl::GenCodeFlowUnit to
|
||||
while(flow_buffer_->data_available())
|
||||
|
||||
|
||||
(7) initialization of flow buffer in CaseType with bufferable fields
|
||||
in cases
|
||||
- problem: initialization of buffer occurs in every Parse call,
|
||||
regardless if it was initialized before or not; initialization
|
||||
is correct only on first such occurence
|
||||
- solution: check to buffer_state is to be created always when
|
||||
buffering_state_id is in environment in Type::GenBufferConfig
|
||||
- changed condition from buffering_state_var_field_ to
|
||||
env->GetDataType(buffering_state_id)
|
||||
|
||||
|
||||
(8) allowing init and cleanup code to be redefined, as well as addition
|
||||
of code to FlowEOF calls in analyzer and flow
|
||||
- problem 1: when refining an analyzer or flow definition, additional
|
||||
init and cleanup code was not allowed, if these were already defined
|
||||
before; this leads to problems when adding new members, as these
|
||||
cannot be initialized and destroyed properly
|
||||
- solution: allow init and cleanup code to be specified more than once
|
||||
- changed deifnitions and usage of constructor_helper and
|
||||
destructor_helper to allow for lists of constructor and destructor
|
||||
helpers (similar to member declarations) in pac_analyzer.h and
|
||||
pac_analyzer.cc
|
||||
- problem 2: in some cases, it is desirable to execute code when
|
||||
encountering the end of the input stream, which is not possible in
|
||||
binpac
|
||||
- solution: added a %eof binpac primitive similar to %init, which adds
|
||||
code to the FlowEOF function of an analyzer or a flow
|
Binary file not shown.
|
@ -1,172 +0,0 @@
|
|||
Index: pac_type.h
|
||||
===================================================================
|
||||
--- pac_type.h (revision 4130)
|
||||
+++ pac_type.h (working copy)
|
||||
@@ -78,12 +78,6 @@
|
||||
string EvalByteOrder(Output *out_cc, Env *env) const;
|
||||
|
||||
virtual string EvalMember(const ID *member_id) const;
|
||||
-#if 0
|
||||
- // member_env() is used for finding a member of the type.
|
||||
- // Thus member_env() of a ParameterizedType should return
|
||||
- // ReferredDataType()->env()
|
||||
- // virtual Env *member_env() const;
|
||||
-#endif
|
||||
|
||||
// The variable defined by the type
|
||||
const ID *value_var() const { return value_var_; }
|
||||
@@ -223,6 +217,8 @@
|
||||
|
||||
virtual bool ByteOrderSensitive() const = 0;
|
||||
|
||||
+ bool NeedsBufferingStateVar() const;
|
||||
+
|
||||
void GenBufferingLoop(Output* out_cc, Env* env, int flags);
|
||||
void GenParseBuffer(Output* out_cc, Env* env, int flags);
|
||||
void GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags);
|
||||
Index: lib/binpac_buffer.h
|
||||
===================================================================
|
||||
--- lib/binpac_buffer.h (revision 4130)
|
||||
+++ lib/binpac_buffer.h (working copy)
|
||||
@@ -24,18 +24,18 @@
|
||||
void DiscardData();
|
||||
|
||||
// Whether there is enough data for the frame
|
||||
- bool ready() const{ return message_complete_; }
|
||||
+ bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; }
|
||||
|
||||
inline const_byteptr begin() const
|
||||
{
|
||||
- BINPAC_ASSERT(message_complete_);
|
||||
+ BINPAC_ASSERT(ready());
|
||||
return ( buffer_n_ == 0 ) ?
|
||||
orig_data_begin_ : buffer_;
|
||||
}
|
||||
|
||||
inline const_byteptr end() const
|
||||
{
|
||||
- BINPAC_ASSERT(message_complete_);
|
||||
+ BINPAC_ASSERT(ready());
|
||||
if ( buffer_n_ == 0 )
|
||||
{
|
||||
BINPAC_ASSERT(frame_length_ >= 0);
|
||||
Index: pac_type.cc
|
||||
===================================================================
|
||||
--- pac_type.cc (revision 4130)
|
||||
+++ pac_type.cc (working copy)
|
||||
@@ -285,9 +285,8 @@
|
||||
parsing_complete_var, extern_type_bool->Clone());
|
||||
parsing_complete_var_field_->Prepare(env);
|
||||
|
||||
- if ( ( buffer_mode() == BUFFER_BY_LENGTH ||
|
||||
- buffer_mode() == BUFFER_BY_LINE ) &&
|
||||
- ! env->GetDataType(buffering_state_id) )
|
||||
+ if ( NeedsBufferingStateVar() &&
|
||||
+ !env->GetDataType(buffering_state_id) )
|
||||
{
|
||||
buffering_state_var_field_ = new PrivVarField(
|
||||
buffering_state_id->clone(),
|
||||
@@ -387,17 +386,17 @@
|
||||
break;
|
||||
|
||||
case BUFFER_BY_LENGTH:
|
||||
- if ( buffering_state_var_field_ )
|
||||
- {
|
||||
- out_cc->println("if ( %s == 0 )",
|
||||
- env->RValue(buffering_state_id));
|
||||
- out_cc->inc_indent();
|
||||
- out_cc->println("{");
|
||||
- }
|
||||
+ if ( !NeedsBufferingStateVar() )
|
||||
+ break;
|
||||
|
||||
+ ASSERT(env->GetDataType(buffering_state_id));
|
||||
+ out_cc->println("if ( %s == 0 )",
|
||||
+ env->RValue(buffering_state_id));
|
||||
+ out_cc->inc_indent();
|
||||
+ out_cc->println("{");
|
||||
+
|
||||
if ( attr_length_expr_ )
|
||||
{
|
||||
- // frame_buffer_arg = attr_length_expr_->EvalExpr(out_cc, env);
|
||||
frame_buffer_arg = strfmt("%d", InitialBufferLength());
|
||||
}
|
||||
else if ( attr_restofflow_ )
|
||||
@@ -407,7 +406,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
- frame_buffer_arg = strfmt("%d", InitialBufferLength());
|
||||
+ ASSERT(0);
|
||||
}
|
||||
|
||||
out_cc->println("%s->NewFrame(%s, %s);",
|
||||
@@ -415,16 +414,14 @@
|
||||
frame_buffer_arg.c_str(),
|
||||
attr_chunked() ? "true" : "false");
|
||||
|
||||
- if ( buffering_state_var_field_ )
|
||||
- {
|
||||
- out_cc->println("%s = 1;",
|
||||
- env->LValue(buffering_state_id));
|
||||
- out_cc->println("}");
|
||||
- out_cc->dec_indent();
|
||||
- }
|
||||
+ out_cc->println("%s = 1;",
|
||||
+ env->LValue(buffering_state_id));
|
||||
+ out_cc->println("}");
|
||||
+ out_cc->dec_indent();
|
||||
break;
|
||||
|
||||
case BUFFER_BY_LINE:
|
||||
+ ASSERT(env->GetDataType(buffering_state_id));
|
||||
out_cc->println("if ( %s == 0 )",
|
||||
env->RValue(buffering_state_id));
|
||||
out_cc->inc_indent();
|
||||
@@ -890,6 +887,25 @@
|
||||
return ! attr_byteorder_expr() && ByteOrderSensitive();
|
||||
}
|
||||
|
||||
+bool Type::NeedsBufferingStateVar() const
|
||||
+ {
|
||||
+ if ( !incremental_input() )
|
||||
+ return false;
|
||||
+ switch ( buffer_mode() )
|
||||
+ {
|
||||
+ case BUFFER_NOTHING:
|
||||
+ case NOT_BUFFERABLE:
|
||||
+ return false;
|
||||
+ case BUFFER_BY_LINE:
|
||||
+ return true;
|
||||
+ case BUFFER_BY_LENGTH:
|
||||
+ return ( attr_length_expr_ || attr_restofflow_ );
|
||||
+ default:
|
||||
+ ASSERT(0);
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
bool Type::DoTraverse(DataDepVisitor *visitor)
|
||||
{
|
||||
foreach (i, FieldList, fields_)
|
||||
Index: pac_flow.cc
|
||||
===================================================================
|
||||
--- pac_flow.cc (revision 4130)
|
||||
+++ pac_flow.cc (working copy)
|
||||
@@ -224,15 +224,13 @@
|
||||
out_cc->println("catch ( Exception const &e )");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
- out_cc->println("DEBUG_MSG(\"%%.6f binpac exception: %%s\\n\", network_time(), e.c_msg());");
|
||||
GenCleanUpCode(out_cc);
|
||||
if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT )
|
||||
{
|
||||
out_cc->println("%s->DiscardData();",
|
||||
env_->LValue(flow_buffer_id));
|
||||
- out_cc->println("BINPAC_ASSERT(!%s->ready());",
|
||||
- env_->RValue(flow_buffer_id));
|
||||
}
|
||||
+ out_cc->println("throw e;");
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
|
|
@ -1,716 +0,0 @@
|
|||
#!/bin/sh
|
||||
##
|
||||
## GNU shtool -- The GNU Portable Shell Tool
|
||||
## Copyright (c) 1994-2000 Ralf S. Engelschall <rse@engelschall.com>
|
||||
##
|
||||
## See http://www.gnu.org/software/shtool/ for more information.
|
||||
## See ftp://ftp.gnu.org/gnu/shtool/ for latest version.
|
||||
##
|
||||
## Version 1.4.9 (16-Apr-2000)
|
||||
## Ingredients: 3/17 available modules
|
||||
##
|
||||
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; either version 2 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
## General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software
|
||||
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
## USA, or contact Ralf S. Engelschall <rse@engelschall.com>.
|
||||
##
|
||||
## Notice: Given that you include this file verbatim into your own
|
||||
## source tree, you are justified in saying that it remains separate
|
||||
## from your package, and that this way you are simply just using GNU
|
||||
## shtool. So, in this situation, there is no requirement that your
|
||||
## package itself is licensed under the GNU General Public License in
|
||||
## order to take advantage of GNU shtool.
|
||||
##
|
||||
|
||||
##
|
||||
## Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]
|
||||
##
|
||||
## Available commands:
|
||||
## echo Print string with optional construct expansion
|
||||
## install Install a program, script or datafile
|
||||
## mkdir Make one or more directories
|
||||
##
|
||||
## Not available commands (because module was not built-in):
|
||||
## mdate Pretty-print modification time of a file or dir
|
||||
## table Pretty-print a field-separated list as a table
|
||||
## prop Display progress with a running propeller
|
||||
## move Move files with simultaneous substitution
|
||||
## mkln Make link with calculation of relative paths
|
||||
## mkshadow Make a shadow tree through symbolic links
|
||||
## fixperm Fix file permissions inside a source tree
|
||||
## tarball Roll distribution tarballs
|
||||
## guessos Simple operating system guesser
|
||||
## arx Extended archive command
|
||||
## slo Separate linker options by library class
|
||||
## scpp Sharing C Pre-Processor
|
||||
## version Generate and maintain a version information file
|
||||
## path Deal with program paths
|
||||
##
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "$0:Error: invalid command line" 1>&2
|
||||
echo "$0:Hint: run \`$0 -h' for usage" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then
|
||||
echo "This is GNU shtool, version 1.4.9 (16-Apr-2000)"
|
||||
echo "Copyright (c) 1994-2000 Ralf S. Engelschall <rse@engelschall.com>"
|
||||
echo "Report bugs to <bug-shtool@gnu.org>"
|
||||
echo ''
|
||||
echo "Usage: shtool [<options>] [<cmd-name> [<cmd-options>] [<cmd-args>]]"
|
||||
echo ''
|
||||
echo 'Available global <options>:'
|
||||
echo ' -v, --version display shtool version information'
|
||||
echo ' -h, --help display shtool usage help page (this one)'
|
||||
echo ' -d, --debug display shell trace information'
|
||||
echo ''
|
||||
echo 'Available <cmd-name> [<cmd-options>] [<cmd-args>]:'
|
||||
echo ' echo [-n] [-e] [<str> ...]'
|
||||
echo ' install [-v] [-t] [-c] [-C] [-s] [-m<mode>] [-o<owner>] [-g<group>]'
|
||||
echo ' [-e<ext>] <file> <path>'
|
||||
echo ' mkdir [-t] [-f] [-p] [-m<mode>] <dir> [<dir> ...]'
|
||||
echo ''
|
||||
echo 'Not available <cmd-name> (because module was not built-in):'
|
||||
echo ' mdate [-n] [-z] [-s] [-d] [-f<str>] [-o<spec>] <path>'
|
||||
echo ' table [-F<sep>] [-w<width>] [-c<cols>] [-s<strip>] <str><sep><str>...'
|
||||
echo ' prop [-p<str>]'
|
||||
echo ' move [-v] [-t] [-e] [-p] <src-file> <dst-file>'
|
||||
echo ' mkln [-t] [-f] [-s] <src-path> [<src-path> ...] <dst-path>'
|
||||
echo ' mkshadow [-v] [-t] [-a] <src-dir> <dst-dir>'
|
||||
echo ' fixperm [-v] [-t] <path> [<path> ...]'
|
||||
echo ' tarball [-t] [-v] [-o <tarball>] [-c <prog>] [-d <dir>] [-u'
|
||||
echo ' <user>] [-g <group>] [-e <pattern>] <path> [<path> ...]'
|
||||
echo ' guessos '
|
||||
echo ' arx [-t] [-C<cmd>] <op> <archive> [<file> ...]'
|
||||
echo ' slo [-p<str>] -- -L<dir> -l<lib> [-L<dir> -l<lib> ...]'
|
||||
echo ' scpp [-v] [-p] [-f<filter>] [-o<ofile>] [-t<tfile>] [-M<mark>]'
|
||||
echo ' [-D<dname>] [-C<cname>] <file> [<file> ...]'
|
||||
echo ' version [-l<lang>] [-n<name>] [-p<prefix>] [-s<version>] [-i<knob>]'
|
||||
echo ' [-d<type>] <file>'
|
||||
echo ' path [-s] [-r] [-d] [-b] [-m] [-p<path>] <str> [<str> ...]'
|
||||
echo ''
|
||||
exit 0
|
||||
fi
|
||||
if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then
|
||||
echo "GNU shtool 1.4.9 (16-Apr-2000)"
|
||||
exit 0
|
||||
fi
|
||||
if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then
|
||||
shift
|
||||
set -x
|
||||
fi
|
||||
name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'`
|
||||
case "$name" in
|
||||
echo|install|mkdir )
|
||||
# implicit tool command selection
|
||||
tool="$name"
|
||||
;;
|
||||
* )
|
||||
# explicit tool command selection
|
||||
tool="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
arg_spec=""
|
||||
opt_spec=""
|
||||
gen_tmpfile=no
|
||||
|
||||
##
|
||||
## DISPATCH INTO SCRIPT PROLOG
|
||||
##
|
||||
|
||||
case $tool in
|
||||
echo )
|
||||
str_tool="echo"
|
||||
str_usage="[-n] [-e] [<str> ...]"
|
||||
arg_spec="0+"
|
||||
opt_spec="n.e."
|
||||
opt_n=no
|
||||
opt_e=no
|
||||
;;
|
||||
install )
|
||||
str_tool="install"
|
||||
str_usage="[-v] [-t] [-c] [-C] [-s] [-m<mode>] [-o<owner>] [-g<group>] [-e<ext>] <file> <path>"
|
||||
arg_spec="2="
|
||||
opt_spec="v.t.c.C.s.m:o:g:e:"
|
||||
opt_v=no
|
||||
opt_t=no
|
||||
opt_c=no
|
||||
opt_C=no
|
||||
opt_s=no
|
||||
opt_m=""
|
||||
opt_o=""
|
||||
opt_g=""
|
||||
opt_e=""
|
||||
;;
|
||||
mkdir )
|
||||
str_tool="mkdir"
|
||||
str_usage="[-t] [-f] [-p] [-m<mode>] <dir> [<dir> ...]"
|
||||
arg_spec="1+"
|
||||
opt_spec="t.f.p.m:"
|
||||
opt_t=no
|
||||
opt_f=no
|
||||
opt_p=no
|
||||
opt_m=""
|
||||
;;
|
||||
-* )
|
||||
echo "$0:Error: unknown option \`$tool'" 2>&1
|
||||
echo "$0:Hint: run \`$0 -h' for usage" 2>&1
|
||||
exit 1
|
||||
;;
|
||||
* )
|
||||
echo "$0:Error: unknown command \`$tool'" 2>&1
|
||||
echo "$0:Hint: run \`$0 -h' for usage" 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
##
|
||||
## COMMON UTILITY CODE
|
||||
##
|
||||
|
||||
# determine name of tool
|
||||
if [ ".$tool" != . ]; then
|
||||
# used inside shtool script
|
||||
toolcmd="$0 $tool"
|
||||
toolcmdhelp="shtool $tool"
|
||||
msgprefix="shtool:$tool"
|
||||
else
|
||||
# used as standalone script
|
||||
toolcmd="$0"
|
||||
toolcmdhelp="sh $0"
|
||||
msgprefix="$str_tool"
|
||||
fi
|
||||
|
||||
# parse argument specification string
|
||||
eval `echo $arg_spec |\
|
||||
sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'`
|
||||
|
||||
# parse option specification string
|
||||
eval `echo h.$opt_spec |\
|
||||
sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'`
|
||||
|
||||
# interate over argument line
|
||||
opt_PREV=''
|
||||
while [ $# -gt 0 ]; do
|
||||
# special option stops processing
|
||||
if [ ".$1" = ".--" ]; then
|
||||
shift
|
||||
break
|
||||
fi
|
||||
|
||||
# determine option and argument
|
||||
opt_ARG_OK=no
|
||||
if [ ".$opt_PREV" != . ]; then
|
||||
# merge previous seen option with argument
|
||||
opt_OPT="$opt_PREV"
|
||||
opt_ARG="$1"
|
||||
opt_ARG_OK=yes
|
||||
opt_PREV=''
|
||||
else
|
||||
# split argument into option and argument
|
||||
case "$1" in
|
||||
-[a-zA-Z0-9]*)
|
||||
eval `echo "x$1" |\
|
||||
sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \
|
||||
-e 's/";\(.*\)$/"; opt_ARG="\1"/'`
|
||||
;;
|
||||
-[a-zA-Z0-9])
|
||||
opt_OPT=`echo "x$1" | cut -c3-`
|
||||
opt_ARG=''
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# eat up option
|
||||
shift
|
||||
|
||||
# determine whether option needs an argument
|
||||
eval "opt_MODE=\$opt_MODE_${opt_OPT}"
|
||||
if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then
|
||||
if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then
|
||||
opt_PREV="$opt_OPT"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
# process option
|
||||
case $opt_MODE in
|
||||
'.' )
|
||||
# boolean option
|
||||
eval "opt_${opt_OPT}=yes"
|
||||
;;
|
||||
':' )
|
||||
# option with argument (multiple occurances override)
|
||||
eval "opt_${opt_OPT}=\"\$opt_ARG\""
|
||||
;;
|
||||
'+' )
|
||||
# option with argument (multiple occurances append)
|
||||
eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\""
|
||||
;;
|
||||
* )
|
||||
echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2
|
||||
echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
if [ ".$opt_PREV" != . ]; then
|
||||
echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2
|
||||
echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# process help option
|
||||
if [ ".$opt_h" = .yes ]; then
|
||||
echo "Usage: $toolcmdhelp $str_usage"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# complain about incorrect number of arguments
|
||||
case $arg_MODE in
|
||||
'=' )
|
||||
if [ $# -ne $arg_NUMS ]; then
|
||||
echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2
|
||||
echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
'+' )
|
||||
if [ $# -lt $arg_NUMS ]; then
|
||||
echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2
|
||||
echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# establish a temporary file on request
|
||||
if [ ".$gen_tmpfile" = .yes ]; then
|
||||
if [ ".$TMPDIR" != . ]; then
|
||||
tmpdir="$TMPDIR"
|
||||
elif [ ".$TEMPDIR" != . ]; then
|
||||
tmpdir="$TEMPDIR"
|
||||
else
|
||||
tmpdir="/tmp"
|
||||
fi
|
||||
tmpfile="$tmpdir/.shtool.$$"
|
||||
rm -f $tmpfile >/dev/null 2>&1
|
||||
touch $tmpfile
|
||||
fi
|
||||
|
||||
##
|
||||
## DISPATCH INTO SCRIPT BODY
|
||||
##
|
||||
|
||||
case $tool in
|
||||
|
||||
echo )
|
||||
##
|
||||
## echo -- Print string with optional construct expansion
|
||||
## Copyright (c) 1998-2000 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for WML as buildinfo
|
||||
##
|
||||
|
||||
text="$*"
|
||||
|
||||
# check for broken escape sequence expansion
|
||||
seo=''
|
||||
bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'`
|
||||
if [ ".$bytes" != .3 ]; then
|
||||
bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'`
|
||||
if [ ".$bytes" = .3 ]; then
|
||||
seo='-E'
|
||||
fi
|
||||
fi
|
||||
|
||||
# check for existing -n option (to suppress newline)
|
||||
minusn=''
|
||||
bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'`
|
||||
if [ ".$bytes" = .3 ]; then
|
||||
minusn='-n'
|
||||
fi
|
||||
|
||||
# determine terminal bold sequence
|
||||
term_bold=''
|
||||
term_norm=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then
|
||||
case $TERM in
|
||||
# for the most important terminal types we directly know the sequences
|
||||
xterm|xterm*|vt220|vt220*)
|
||||
term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
|
||||
term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
|
||||
;;
|
||||
vt100|vt100*)
|
||||
term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
|
||||
term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
|
||||
;;
|
||||
# for all others, we try to use a possibly existing `tput' or `tcout' utility
|
||||
* )
|
||||
paths=`echo $PATH | sed -e 's/:/ /g'`
|
||||
for tool in tput tcout; do
|
||||
for dir in $paths; do
|
||||
if [ -r "$dir/$tool" ]; then
|
||||
for seq in bold md smso; do # 'smso' is last
|
||||
bold="`$dir/$tool $seq 2>/dev/null`"
|
||||
if [ ".$bold" != . ]; then
|
||||
term_bold="$bold"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ ".$term_bold" != . ]; then
|
||||
for seq in sgr0 me rmso reset; do # 'reset' is last
|
||||
norm="`$dir/$tool $seq 2>/dev/null`"
|
||||
if [ ".$norm" != . ]; then
|
||||
term_norm="$norm"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ ".$term_bold" != . -a ".$term_norm" != . ]; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
if [ ".$term_bold" = . -o ".$term_norm" = . ]; then
|
||||
echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2
|
||||
fi
|
||||
fi
|
||||
|
||||
# determine user name
|
||||
username=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uU]'`" != . ]; then
|
||||
username="$LOGNAME"
|
||||
if [ ".$username" = . ]; then
|
||||
username="$USER"
|
||||
if [ ".$username" = . ]; then
|
||||
username="`(whoami) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$username" = . ]; then
|
||||
username="`(who am i) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$username" = . ]; then
|
||||
username='unknown'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# determine user id
|
||||
userid=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then
|
||||
userid="`(id -u) 2>/dev/null`"
|
||||
if [ ".$userid" = . ]; then
|
||||
str="`(id) 2>/dev/null`"
|
||||
if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then
|
||||
userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*//'`
|
||||
fi
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid=`(ypcat passwd) 2>/dev/null |
|
||||
egrep "^${username}:" | \
|
||||
sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'`
|
||||
if [ ".$userid" = . ]; then
|
||||
userid='?'
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# determine host name
|
||||
hostname=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then
|
||||
hostname="`(uname -n) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$hostname" = . ]; then
|
||||
hostname="`(hostname) 2>/dev/null |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$hostname" = . ]; then
|
||||
hostname='unknown'
|
||||
fi
|
||||
fi
|
||||
case $hostname in
|
||||
*.* )
|
||||
domainname=".`echo $hostname | cut -d. -f2-`"
|
||||
hostname="`echo $hostname | cut -d. -f1`"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# determine domain name
|
||||
domainname=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then
|
||||
if [ ".$domainname" = . ]; then
|
||||
if [ -f /etc/resolv.conf ]; then
|
||||
domainname="`egrep '^[ ]*domain' /etc/resolv.conf | head -1 |\
|
||||
sed -e 's/.*domain//' \
|
||||
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
|
||||
-e 's/^\.//' -e 's/^/./' |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
if [ ".$domainname" = . ]; then
|
||||
domainname="`egrep '^[ ]*search' /etc/resolv.conf | head -1 |\
|
||||
sed -e 's/.*search//' \
|
||||
-e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \
|
||||
-e 's/ .*//' -e 's/ .*//' \
|
||||
-e 's/^\.//' -e 's/^/./' |\
|
||||
awk '{ printf("%s", $1); }'`"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# determine current time
|
||||
time_day=''
|
||||
time_month=''
|
||||
time_year=''
|
||||
time_monthname=''
|
||||
if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then
|
||||
time_day=`date '+%d'`
|
||||
time_month=`date '+%m'`
|
||||
time_year=`date '+%Y' 2>/dev/null`
|
||||
if [ ".$time_year" = . ]; then
|
||||
time_year=`date '+%y'`
|
||||
case $time_year in
|
||||
[5-9][0-9]) time_year="19$time_year" ;;
|
||||
[0-4][0-9]) time_year="20$time_year" ;;
|
||||
esac
|
||||
fi
|
||||
case $time_month in
|
||||
1|01) time_monthname='Jan' ;;
|
||||
2|02) time_monthname='Feb' ;;
|
||||
3|03) time_monthname='Mar' ;;
|
||||
4|04) time_monthname='Apr' ;;
|
||||
5|05) time_monthname='May' ;;
|
||||
6|06) time_monthname='Jun' ;;
|
||||
7|07) time_monthname='Jul' ;;
|
||||
8|08) time_monthname='Aug' ;;
|
||||
9|09) time_monthname='Sep' ;;
|
||||
10) time_monthname='Oct' ;;
|
||||
11) time_monthname='Nov' ;;
|
||||
12) time_monthname='Dec' ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# expand special ``%x'' constructs
|
||||
if [ ".$opt_e" = .yes ]; then
|
||||
text=`echo $seo "$text" |\
|
||||
sed -e "s/%B/${term_bold}/g" \
|
||||
-e "s/%b/${term_norm}/g" \
|
||||
-e "s/%u/${username}/g" \
|
||||
-e "s/%U/${userid}/g" \
|
||||
-e "s/%h/${hostname}/g" \
|
||||
-e "s/%d/${domainname}/g" \
|
||||
-e "s/%D/${time_day}/g" \
|
||||
-e "s/%M/${time_month}/g" \
|
||||
-e "s/%Y/${time_year}/g" \
|
||||
-e "s/%m/${time_monthname}/g" 2>/dev/null`
|
||||
fi
|
||||
|
||||
# create output
|
||||
if [ .$opt_n = .no ]; then
|
||||
echo $seo "$text"
|
||||
else
|
||||
# the harder part: echo -n is best, because
|
||||
# awk may complain about some \xx sequences.
|
||||
if [ ".$minusn" != . ]; then
|
||||
echo $seo $minusn "$text"
|
||||
else
|
||||
echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
install )
|
||||
##
|
||||
## install -- Install a program, script or datafile
|
||||
## Copyright (c) 1997-2000 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for shtool
|
||||
##
|
||||
|
||||
src="$1"
|
||||
dst="$2"
|
||||
|
||||
# If destination is a directory, append the input filename
|
||||
if [ -d $dst ]; then
|
||||
dst=`echo "$dst" | sed -e 's:/$::'`
|
||||
dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'`
|
||||
dst="$dst/$dstfile"
|
||||
fi
|
||||
|
||||
# Add a possible extension to src and dst
|
||||
if [ ".$opt_e" != . ]; then
|
||||
src="$src$opt_e"
|
||||
dst="$dst$opt_e"
|
||||
fi
|
||||
|
||||
# Check for correct arguments
|
||||
if [ ".$src" = ".$dst" ]; then
|
||||
echo "$msgprefix:Error: source and destination are the same" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make a temp file name in the destination directory
|
||||
dstdir=`echo $dst | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'`
|
||||
dsttmp="$dstdir/#INST@$$#"
|
||||
|
||||
# Verbosity
|
||||
if [ ".$opt_v" = .yes ]; then
|
||||
echo "$src -> $dst" 1>&2
|
||||
fi
|
||||
|
||||
# Copy or move the file name to the temp name
|
||||
# (because we might be not allowed to change the source)
|
||||
if [ ".$opt_C" = .yes ]; then
|
||||
opt_c=yes
|
||||
fi
|
||||
if [ ".$opt_c" = .yes ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "cp $src $dsttmp" 1>&2
|
||||
fi
|
||||
cp $src $dsttmp || exit $?
|
||||
else
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "mv $src $dsttmp" 1>&2
|
||||
fi
|
||||
mv $src $dsttmp || exit $?
|
||||
fi
|
||||
|
||||
# Adjust the target file
|
||||
# (we do chmod last to preserve setuid bits)
|
||||
if [ ".$opt_s" = .yes ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "strip $dsttmp" 1>&2
|
||||
fi
|
||||
strip $dsttmp || exit $?
|
||||
fi
|
||||
if [ ".$opt_o" != . ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chown $opt_o $dsttmp" 1>&2
|
||||
fi
|
||||
chown $opt_o $dsttmp || exit $?
|
||||
fi
|
||||
if [ ".$opt_g" != . ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chgrp $opt_g $dsttmp" 1>&2
|
||||
fi
|
||||
chgrp $opt_g $dsttmp || exit $?
|
||||
fi
|
||||
if [ ".$opt_m" != . ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chmod $opt_m $dsttmp" 1>&2
|
||||
fi
|
||||
chmod $opt_m $dsttmp || exit $?
|
||||
fi
|
||||
|
||||
# Determine whether to do a quick install
|
||||
# (has to be done _after_ the strip was already done)
|
||||
quick=no
|
||||
if [ ".$opt_C" = .yes ]; then
|
||||
if [ -r $dst ]; then
|
||||
if cmp -s $src $dst; then
|
||||
quick=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Finally install the file to the real destination
|
||||
if [ $quick = yes ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "rm -f $dsttmp" 1>&2
|
||||
fi
|
||||
rm -f $dsttmp
|
||||
else
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "rm -f $dst && mv $dsttmp $dst" 1>&2
|
||||
fi
|
||||
rm -f $dst && mv $dsttmp $dst
|
||||
fi
|
||||
;;
|
||||
|
||||
mkdir )
|
||||
##
|
||||
## mkdir -- Make one or more directories
|
||||
## Copyright (c) 1996-2000 Ralf S. Engelschall <rse@engelschall.com>
|
||||
## Originally written for public domain by Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
## Cleaned up and enhanced for shtool
|
||||
##
|
||||
|
||||
errstatus=0
|
||||
for p in ${1+"$@"}; do
|
||||
# if the directory already exists...
|
||||
if [ -d "$p" ]; then
|
||||
if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then
|
||||
echo "$msgprefix:Error: directory already exists: $p" 1>&2
|
||||
errstatus=1
|
||||
break
|
||||
else
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
# if the directory has to be created...
|
||||
if [ ".$opt_p" = .no ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "mkdir $p" 1>&2
|
||||
fi
|
||||
mkdir $p || errstatus=$?
|
||||
else
|
||||
# the smart situation
|
||||
set fnord `echo ":$p" |\
|
||||
sed -e 's/^:\//%/' \
|
||||
-e 's/^://' \
|
||||
-e 's/\// /g' \
|
||||
-e 's/^%/\//'`
|
||||
shift
|
||||
pathcomp=''
|
||||
for d in ${1+"$@"}; do
|
||||
pathcomp="$pathcomp$d"
|
||||
case "$pathcomp" in
|
||||
-* ) pathcomp="./$pathcomp" ;;
|
||||
esac
|
||||
if [ ! -d "$pathcomp" ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
fi
|
||||
mkdir $pathcomp || errstatus=$?
|
||||
if [ ".$opt_m" != . ]; then
|
||||
if [ ".$opt_t" = .yes ]; then
|
||||
echo "chmod $opt_m $pathcomp" 1>&2
|
||||
fi
|
||||
chmod $opt_m $pathcomp || errstatus=$?
|
||||
fi
|
||||
fi
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
fi
|
||||
done
|
||||
exit $errstatus
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
##EOF##
|
|
@ -1,62 +0,0 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AM_YFLAGS = -d -t -v
|
||||
AM_CPPFLAGS = -W -Wall -Wno-unused
|
||||
|
||||
noinst_PROGRAMS = binpac
|
||||
|
||||
binpac_SOURCES = \
|
||||
pac_scan.ll pac_parse.yy \
|
||||
pac_action.cc \
|
||||
pac_analyzer.cc \
|
||||
pac_array.cc \
|
||||
pac_attr.cc \
|
||||
pac_btype.cc \
|
||||
pac_case.cc \
|
||||
pac_conn.cc \
|
||||
pac_context.cc \
|
||||
pac_cstr.cc \
|
||||
pac_datadep.cc \
|
||||
pac_dataptr.cc \
|
||||
pac_dataunit.cc \
|
||||
pac_decl.cc \
|
||||
pac_embedded.cc \
|
||||
pac_enum.cc \
|
||||
pac_expr.cc \
|
||||
pac_exttype.cc \
|
||||
pac_field.cc \
|
||||
pac_flow.cc \
|
||||
pac_func.cc \
|
||||
pac_id.cc \
|
||||
pac_inputbuf.cc \
|
||||
pac_let.cc \
|
||||
pac_param.cc \
|
||||
pac_paramtype.cc \
|
||||
pac_primitive.cc \
|
||||
pac_record.cc \
|
||||
pac_redef.cc \
|
||||
pac_regex.cc \
|
||||
pac_state.cc \
|
||||
pac_strtype.cc \
|
||||
pac_type.cc \
|
||||
pac_typedecl.cc \
|
||||
pac_withinput.cc \
|
||||
pac_output.cc pac_utils.cc pac_exception.cc \
|
||||
pac_main.cc \
|
||||
pac_action.h pac_analyzer.h pac_array.h pac_attr.h pac_btype.h \
|
||||
pac_case.h pac_cclass.h pac_common.h pac_conn.h pac_context.h \
|
||||
pac_cstr.h pac_ctype.h pac_datadep.h pac_dataptr.h pac_dataunit.h \
|
||||
pac_dbg.h pac_decl-inl.h pac_decl.h pac_embedded.h pac_enum.h \
|
||||
pac_exception.h pac_expr.h pac_exttype.h pac_field.h pac_flow.h \
|
||||
pac_func.h pac_id.h pac_inputbuf.h pac_let.h pac_number.h \
|
||||
pac_output.h pac_param.h pac_paramtype.h pac_parse.h pac_primitive.h \
|
||||
pac_record.h pac_redef.h pac_regex.h pac_state.h pac_strtype.h \
|
||||
pac_type.h pac_typedecl.h pac_utils.h pac_varfield.h pac_withinput.h
|
||||
|
||||
EXTRA_DIST = pac_expr.def pac_type.def pac_externtype.def
|
||||
|
||||
DISTCLEANFILES = pac_parse.cc pac_parse.h pac_scan.cc y.output
|
||||
|
||||
# Manual rules below:
|
||||
|
||||
pac_scan.o: pac_parse.h
|
|
@ -1,119 +0,0 @@
|
|||
#include "pac_embedded.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_type.h"
|
||||
#include "pac_typedecl.h"
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include "pac_action.h"
|
||||
|
||||
AnalyzerAction::AnalyzerAction(ID *action_id,
|
||||
When when,
|
||||
ActionParam *param,
|
||||
EmbeddedCode *code)
|
||||
: AnalyzerElement(ACTION),
|
||||
action_id_(action_id),
|
||||
when_(when),
|
||||
param_(param),
|
||||
code_(code),
|
||||
analyzer_(0)
|
||||
{
|
||||
}
|
||||
|
||||
AnalyzerAction::~AnalyzerAction()
|
||||
{
|
||||
delete action_id_;
|
||||
delete param_;
|
||||
delete code_;
|
||||
}
|
||||
|
||||
string AnalyzerAction::action_function() const
|
||||
{
|
||||
return strfmt("Action_%s", action_id_->Name());
|
||||
}
|
||||
|
||||
void AnalyzerAction::InstallHook(AnalyzerDecl *analyzer)
|
||||
{
|
||||
ASSERT(0);
|
||||
analyzer_ = analyzer;
|
||||
// param_->MainDataType()->InstallAction(this);
|
||||
}
|
||||
|
||||
void AnalyzerAction::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
|
||||
{
|
||||
Env action_func_env(decl->env(), this);
|
||||
action_func_env.AddID(param_->id(),
|
||||
TEMP_VAR,
|
||||
param_->DataType());
|
||||
action_func_env.SetEvaluated(param_->id());
|
||||
|
||||
string action_func_proto =
|
||||
strfmt("%s(%s)",
|
||||
action_function().c_str(),
|
||||
ParamDecls(&action_func_env).c_str());
|
||||
|
||||
out_h->println("void %s;", action_func_proto.c_str());
|
||||
|
||||
out_cc->println("void %s::%s",
|
||||
decl->class_name().c_str(),
|
||||
action_func_proto.c_str());
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
code_->GenCode(out_cc, &action_func_env);
|
||||
|
||||
out_cc->println("");
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("");
|
||||
}
|
||||
|
||||
string AnalyzerAction::ParamDecls(Env *env) const
|
||||
{
|
||||
return param_->DeclStr(env);
|
||||
}
|
||||
|
||||
Type *ActionParam::MainDataType() const
|
||||
{
|
||||
// Note: this is not equal to DataType()
|
||||
Type *main_type = TypeDecl::LookUpType(type()->type_id());
|
||||
|
||||
if ( ! main_type )
|
||||
{
|
||||
throw Exception(type()->type_id(),
|
||||
"type not defined");
|
||||
}
|
||||
|
||||
return main_type;
|
||||
}
|
||||
|
||||
Type *ActionParam::DataType() const
|
||||
{
|
||||
Type *main_type = MainDataType();
|
||||
|
||||
if ( ! type()->field_id() )
|
||||
{
|
||||
return main_type;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type *member_type =
|
||||
main_type->MemberDataType(type()->field_id());
|
||||
if ( ! member_type )
|
||||
{
|
||||
throw Exception(type()->field_id(),
|
||||
fmt("cannot find member type for `%s.%s'",
|
||||
type()->type_id()->Name(),
|
||||
type()->field_id()->Name()));
|
||||
}
|
||||
return member_type;
|
||||
}
|
||||
}
|
||||
|
||||
string ActionParam::DeclStr(Env *env) const
|
||||
{
|
||||
return strfmt("%s %s",
|
||||
DataType()->DataTypeStr().c_str(),
|
||||
env->LValue(id()));
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
#ifndef pac_action_h
|
||||
#define pac_action_h
|
||||
|
||||
// Classes representing analyzer actions.
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_analyzer.h"
|
||||
|
||||
class AnalyzerAction : public AnalyzerElement
|
||||
{
|
||||
public:
|
||||
enum When { BEFORE, AFTER };
|
||||
|
||||
AnalyzerAction(ID *action_id,
|
||||
When when,
|
||||
ActionParam *param,
|
||||
EmbeddedCode *code);
|
||||
|
||||
~AnalyzerAction();
|
||||
|
||||
When when() const { return when_; }
|
||||
ActionParam *param() const { return param_; }
|
||||
AnalyzerDecl *analyzer() const { return analyzer_; }
|
||||
string action_function() const;
|
||||
|
||||
// Generate function prototype and code for the action
|
||||
void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl);
|
||||
|
||||
// Install the hook at the corresponding data type parsing
|
||||
// function to invoke the action.
|
||||
void InstallHook(AnalyzerDecl *analyzer);
|
||||
|
||||
private:
|
||||
string ParamDecls(Env *env) const;
|
||||
|
||||
ID *action_id_;
|
||||
When when_;
|
||||
ActionParam *param_;
|
||||
EmbeddedCode *code_;
|
||||
AnalyzerDecl *analyzer_;
|
||||
};
|
||||
|
||||
class ActionParam
|
||||
{
|
||||
public:
|
||||
ActionParam(const ID *id, ActionParamType *type)
|
||||
: id_(id), type_(type) {}
|
||||
|
||||
const ID *id() const { return id_; }
|
||||
ActionParamType *type() const { return type_; }
|
||||
|
||||
Type *MainDataType() const;
|
||||
Type *DataType() const;
|
||||
string DeclStr(Env *env) const;
|
||||
|
||||
private:
|
||||
const ID *id_;
|
||||
ActionParamType *type_;
|
||||
};
|
||||
|
||||
class ActionParamType
|
||||
{
|
||||
public:
|
||||
ActionParamType(const ID *type_id, const ID *field_id = 0)
|
||||
: type_id_(type_id), field_id_(field_id) {}
|
||||
|
||||
const ID *type_id() const { return type_id_; }
|
||||
const ID *field_id() const { return field_id_; }
|
||||
|
||||
protected:
|
||||
const ID *type_id_, *field_id_;
|
||||
};
|
||||
|
||||
#endif // pac_action_h
|
|
@ -1,358 +0,0 @@
|
|||
#include "pac_action.h"
|
||||
#include "pac_context.h"
|
||||
#include "pac_embedded.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_flow.h"
|
||||
#include "pac_func.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_param.h"
|
||||
#include "pac_paramtype.h"
|
||||
#include "pac_state.h"
|
||||
#include "pac_type.h"
|
||||
#include "pac_varfield.h"
|
||||
|
||||
#include "pac_analyzer.h"
|
||||
|
||||
AnalyzerDecl::AnalyzerDecl(ID *id,
|
||||
DeclType decl_type,
|
||||
ParamList *params)
|
||||
: TypeDecl(id, params, new DummyType())
|
||||
{
|
||||
decl_type_ = decl_type;
|
||||
|
||||
statevars_ = new StateVarList();
|
||||
actions_ = new AnalyzerActionList();
|
||||
helpers_ = new AnalyzerHelperList();
|
||||
functions_ = new FunctionList();
|
||||
|
||||
constructor_helpers_ = new AnalyzerHelperList();
|
||||
destructor_helpers_ = new AnalyzerHelperList();
|
||||
eof_helpers_ = new AnalyzerHelperList();
|
||||
|
||||
SetAnalyzerContext();
|
||||
|
||||
env_ = 0;
|
||||
}
|
||||
|
||||
AnalyzerDecl::~AnalyzerDecl()
|
||||
{
|
||||
delete_list(StateVarList, statevars_);
|
||||
delete_list(AnalyzerActionList, actions_);
|
||||
delete_list(AnalyzerHelperList, helpers_);
|
||||
delete_list(FunctionList, functions_);
|
||||
delete_list(ParamList, params_);
|
||||
delete_list(AnalyzerHelperList, constructor_helpers_);
|
||||
delete_list(AnalyzerHelperList, destructor_helpers_);
|
||||
delete_list(AnalyzerHelperList, eof_helpers_);
|
||||
}
|
||||
|
||||
void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist)
|
||||
{
|
||||
ASSERT(! env_);
|
||||
foreach(i, AnalyzerElementList, elemlist)
|
||||
{
|
||||
AnalyzerElement *elem = *i;
|
||||
switch ( elem->type() )
|
||||
{
|
||||
case AnalyzerElement::STATE:
|
||||
{
|
||||
ASSERT(0);
|
||||
AnalyzerState *state_elem =
|
||||
(AnalyzerState *) elem;
|
||||
statevars_->insert(
|
||||
statevars_->end(),
|
||||
state_elem->statevars()->begin(),
|
||||
state_elem->statevars()->end());
|
||||
}
|
||||
break;
|
||||
case AnalyzerElement::ACTION:
|
||||
{
|
||||
ASSERT(0);
|
||||
AnalyzerAction *action_elem =
|
||||
(AnalyzerAction *) elem;
|
||||
actions_->push_back(action_elem);
|
||||
}
|
||||
break;
|
||||
case AnalyzerElement::HELPER:
|
||||
{
|
||||
AnalyzerHelper *helper_elem =
|
||||
(AnalyzerHelper *) elem;
|
||||
|
||||
switch ( helper_elem->helper_type() )
|
||||
{
|
||||
case AnalyzerHelper::INIT_CODE:
|
||||
constructor_helpers_->push_back(helper_elem);
|
||||
break;
|
||||
case AnalyzerHelper::CLEANUP_CODE:
|
||||
destructor_helpers_->push_back(helper_elem);
|
||||
break;
|
||||
case AnalyzerHelper::EOF_CODE:
|
||||
eof_helpers_->push_back(helper_elem);
|
||||
break;
|
||||
default:
|
||||
helpers_->push_back(helper_elem);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AnalyzerElement::FUNCTION:
|
||||
{
|
||||
AnalyzerFunction *func_elem =
|
||||
(AnalyzerFunction *) elem;
|
||||
Function *func = func_elem->function();
|
||||
func->set_analyzer_decl(this);
|
||||
functions_->push_back(func);
|
||||
}
|
||||
break;
|
||||
case AnalyzerElement::FLOW:
|
||||
{
|
||||
AnalyzerFlow *flow_elem =
|
||||
(AnalyzerFlow *) elem;
|
||||
ProcessFlowElement(flow_elem);
|
||||
}
|
||||
break;
|
||||
case AnalyzerElement::DATAUNIT:
|
||||
{
|
||||
AnalyzerDataUnit *dataunit_elem =
|
||||
(AnalyzerDataUnit *) elem;
|
||||
ProcessDataUnitElement(dataunit_elem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string AnalyzerDecl::class_name() const
|
||||
{
|
||||
return id_->Name();
|
||||
}
|
||||
|
||||
void AnalyzerDecl::Prepare()
|
||||
{
|
||||
TypeDecl::Prepare();
|
||||
|
||||
ASSERT(statevars_->empty());
|
||||
ASSERT(actions_->empty());
|
||||
|
||||
foreach(i, FunctionList, functions_)
|
||||
{
|
||||
Function *function = *i;
|
||||
function->Prepare(env_);
|
||||
}
|
||||
foreach(i, StateVarList, statevars_)
|
||||
{
|
||||
StateVar *statevar = *i;
|
||||
env_->AddID(statevar->id(), STATE_VAR, statevar->type());
|
||||
}
|
||||
foreach(i, AnalyzerActionList, actions_)
|
||||
{
|
||||
AnalyzerAction *action = *i;
|
||||
action->InstallHook(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenForwardDeclaration(Output* out_h)
|
||||
{
|
||||
out_h->println("class %s;", class_name().c_str());
|
||||
foreach(i, FunctionList, functions_)
|
||||
{
|
||||
Function *function = *i;
|
||||
function->GenForwardDeclaration(out_h);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenActions(Output *out_h, Output *out_cc)
|
||||
{
|
||||
foreach(i, AnalyzerActionList, actions_)
|
||||
{
|
||||
(*i)->GenCode(out_h, out_cc, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenHelpers(Output *out_h, Output *out_cc)
|
||||
{
|
||||
foreach(i, AnalyzerHelperList, helpers_)
|
||||
{
|
||||
(*i)->GenCode(out_h, out_cc, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenPubDecls(Output *out_h, Output *out_cc)
|
||||
{
|
||||
TypeDecl::GenPubDecls(out_h, out_cc);
|
||||
|
||||
GenProcessFunc(out_h, out_cc);
|
||||
GenGapFunc(out_h, out_cc);
|
||||
GenEOFFunc(out_h, out_cc);
|
||||
out_h->println("");
|
||||
|
||||
if ( ! functions_->empty() )
|
||||
{
|
||||
out_h->println("// Functions");
|
||||
GenFunctions(out_h, out_cc);
|
||||
out_h->println("");
|
||||
}
|
||||
|
||||
// TODO: export public state variables
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenPrivDecls(Output *out_h, Output *out_cc)
|
||||
{
|
||||
TypeDecl::GenPrivDecls(out_h, out_cc);
|
||||
|
||||
if ( ! helpers_->empty() )
|
||||
{
|
||||
out_h->println("");
|
||||
out_h->println("// Additional members");
|
||||
GenHelpers(out_h, out_cc);
|
||||
}
|
||||
|
||||
// TODO: declare state variables
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenInitCode(Output *out_cc)
|
||||
{
|
||||
TypeDecl::GenInitCode(out_cc);
|
||||
foreach(i, AnalyzerHelperList, constructor_helpers_)
|
||||
{
|
||||
(*i)->GenCode(0, out_cc, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenCleanUpCode(Output *out_cc)
|
||||
{
|
||||
TypeDecl::GenCleanUpCode(out_cc);
|
||||
foreach(i, AnalyzerHelperList, destructor_helpers_)
|
||||
{
|
||||
(*i)->GenCode(0, out_cc, this);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenStateVarDecls(Output *out_h)
|
||||
{
|
||||
foreach(i, StateVarList, statevars_)
|
||||
{
|
||||
StateVar *var = *i;
|
||||
var->GenDecl(out_h, env_);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenStateVarSetFunctions(Output *out_h)
|
||||
{
|
||||
foreach(i, StateVarList, statevars_)
|
||||
{
|
||||
StateVar *var = *i;
|
||||
var->GenSetFunction(out_h, env_);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenStateVarInitCode(Output *out_cc)
|
||||
{
|
||||
foreach(i, StateVarList, statevars_)
|
||||
{
|
||||
StateVar *var = *i;
|
||||
var->GenInitCode(out_cc, env_);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenStateVarCleanUpCode(Output *out_cc)
|
||||
{
|
||||
foreach(i, StateVarList, statevars_)
|
||||
{
|
||||
StateVar *var = *i;
|
||||
var->GenCleanUpCode(out_cc, env_);
|
||||
}
|
||||
}
|
||||
|
||||
void AnalyzerDecl::GenFunctions(Output *out_h, Output *out_cc)
|
||||
{
|
||||
foreach(i, FunctionList, functions_)
|
||||
{
|
||||
Function *function = *i;
|
||||
function->GenCode(out_h, out_cc);
|
||||
}
|
||||
}
|
||||
|
||||
AnalyzerState::~AnalyzerState()
|
||||
{
|
||||
// Note: do not delete elements of statevars_, because they
|
||||
// are referenced by the AnalyzerDecl.
|
||||
delete statevars_;
|
||||
}
|
||||
|
||||
AnalyzerHelper::~AnalyzerHelper()
|
||||
{
|
||||
delete code_;
|
||||
}
|
||||
|
||||
void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl)
|
||||
{
|
||||
Output *out = 0;
|
||||
switch ( helper_type_ )
|
||||
{
|
||||
case MEMBER_DECLS:
|
||||
out = out_h;
|
||||
break;
|
||||
case INIT_CODE:
|
||||
case CLEANUP_CODE:
|
||||
case EOF_CODE:
|
||||
out = out_cc;
|
||||
break;
|
||||
}
|
||||
ASSERT(out);
|
||||
code()->GenCode(out, decl->env());
|
||||
}
|
||||
|
||||
FlowField::FlowField(ID *flow_id, ParameterizedType *flow_type)
|
||||
: Field(FLOW_FIELD,
|
||||
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
flow_id, flow_type)
|
||||
{
|
||||
}
|
||||
|
||||
void FlowField::GenInitCode(Output *out_cc, Env *env)
|
||||
{
|
||||
type_->GenPreParsing(out_cc, env);
|
||||
}
|
||||
|
||||
AnalyzerFlow::AnalyzerFlow(Direction dir, ID *type_id, ExprList *params)
|
||||
: AnalyzerElement(FLOW),
|
||||
dir_(dir),
|
||||
type_id_(type_id)
|
||||
{
|
||||
if ( ! params )
|
||||
params = new ExprList();
|
||||
|
||||
// Add "this" to the list of params
|
||||
params->insert(params->begin(), new Expr(this_id->clone()));
|
||||
|
||||
ID *flow_id = ((dir == UP) ? upflow_id : downflow_id)->clone();
|
||||
|
||||
ParameterizedType *flow_type = new ParameterizedType(type_id_, params);
|
||||
|
||||
flow_field_ = new FlowField(flow_id, flow_type);
|
||||
|
||||
flow_decl_ = 0;
|
||||
}
|
||||
|
||||
AnalyzerFlow::~AnalyzerFlow()
|
||||
{
|
||||
delete flow_field_;
|
||||
}
|
||||
|
||||
FlowDecl *AnalyzerFlow::flow_decl()
|
||||
{
|
||||
DEBUG_MSG("Getting flow_decl for %s\n", type_id_->Name());
|
||||
if ( ! flow_decl_ )
|
||||
{
|
||||
Decl *decl = Decl::LookUpDecl(type_id_);
|
||||
if ( decl && decl->decl_type() == Decl::FLOW )
|
||||
flow_decl_ = static_cast<FlowDecl *>(decl);
|
||||
if ( ! flow_decl_ )
|
||||
{
|
||||
throw Exception(this,
|
||||
"cannot find the flow declaration");
|
||||
}
|
||||
}
|
||||
return flow_decl_;
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
#ifndef pac_analyzer_h
|
||||
#define pac_analyzer_h
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_field.h"
|
||||
#include "pac_typedecl.h"
|
||||
|
||||
class AnalyzerElement;
|
||||
class AnalyzerState;
|
||||
class AnalyzerAction; // defined in pac_action.h
|
||||
class AnalyzerHelper;
|
||||
class AnalyzerFlow;
|
||||
class AnalyzerDataUnit;
|
||||
class AnalyzerFunction;
|
||||
class ConnDecl;
|
||||
class FlowDecl;
|
||||
typedef vector<AnalyzerHelper *> AnalyzerHelperList;
|
||||
typedef vector<Function *> FunctionList;
|
||||
|
||||
class AnalyzerDecl : public TypeDecl
|
||||
{
|
||||
public:
|
||||
AnalyzerDecl(ID *id, DeclType decl_type, ParamList *params);
|
||||
~AnalyzerDecl();
|
||||
|
||||
void AddElements(AnalyzerElementList *elemlist);
|
||||
|
||||
void Prepare();
|
||||
void GenForwardDeclaration(Output *out_h);
|
||||
// void GenCode(Output *out_h, Output *out_cc);
|
||||
|
||||
void GenInitCode(Output *out_cc);
|
||||
void GenCleanUpCode(Output *out_cc);
|
||||
|
||||
string class_name() const;
|
||||
// string cookie_name() const;
|
||||
|
||||
protected:
|
||||
virtual void ProcessFlowElement(AnalyzerFlow *flow_elem) = 0;
|
||||
virtual void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) = 0;
|
||||
|
||||
// Generate public/private declarations for member functions and
|
||||
// variables
|
||||
void GenPubDecls(Output *out_h, Output *out_cc);
|
||||
void GenPrivDecls(Output *out_h, Output *out_cc);
|
||||
|
||||
// Generate the NewData() function
|
||||
virtual void GenProcessFunc(Output *out_h, Output *out_cc) = 0;
|
||||
|
||||
// Generate the NewGap() function
|
||||
virtual void GenGapFunc(Output *out_h, Output *out_cc) = 0;
|
||||
|
||||
// Generate the FlowEOF() function
|
||||
virtual void GenEOFFunc(Output *out_h, Output *out_cc) = 0;
|
||||
|
||||
// Generate the functions
|
||||
void GenFunctions(Output *out_h, Output *out_cc);
|
||||
|
||||
// Generate the action functions
|
||||
void GenActions(Output *out_h, Output *out_cc);
|
||||
|
||||
// Generate the helper code segments
|
||||
void GenHelpers(Output *out_h, Output *out_cc);
|
||||
|
||||
// Generate declarations for state variables and their set functions
|
||||
void GenStateVarDecls(Output *out_h);
|
||||
void GenStateVarSetFunctions(Output *out_h);
|
||||
|
||||
// Generate code for initializing and cleaning up (including
|
||||
// memory de-allocating) state variables
|
||||
void GenStateVarInitCode(Output *out_cc);
|
||||
void GenStateVarCleanUpCode(Output *out_cc);
|
||||
|
||||
StateVarList *statevars_;
|
||||
AnalyzerActionList *actions_;
|
||||
AnalyzerHelperList *helpers_;
|
||||
FunctionList *functions_;
|
||||
|
||||
AnalyzerHelperList *constructor_helpers_;
|
||||
AnalyzerHelperList *destructor_helpers_;
|
||||
AnalyzerHelperList *eof_helpers_;
|
||||
};
|
||||
|
||||
class AnalyzerElement : public Object
|
||||
{
|
||||
public:
|
||||
enum ElementType { STATE, ACTION, FUNCTION, HELPER, FLOW, DATAUNIT };
|
||||
AnalyzerElement(ElementType type)
|
||||
: type_(type) {}
|
||||
virtual ~AnalyzerElement() {}
|
||||
|
||||
ElementType type() const { return type_; }
|
||||
|
||||
private:
|
||||
ElementType type_;
|
||||
};
|
||||
|
||||
// A collection of variables representing analyzer states.
|
||||
class AnalyzerState : public AnalyzerElement
|
||||
{
|
||||
public:
|
||||
AnalyzerState(StateVarList *statevars)
|
||||
: AnalyzerElement(STATE),
|
||||
statevars_(statevars) {}
|
||||
~AnalyzerState();
|
||||
|
||||
StateVarList *statevars() const { return statevars_; }
|
||||
|
||||
private:
|
||||
StateVarList *statevars_;
|
||||
};
|
||||
|
||||
// A collection of embedded C++ code
|
||||
class AnalyzerHelper : public AnalyzerElement
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
MEMBER_DECLS,
|
||||
INIT_CODE,
|
||||
CLEANUP_CODE,
|
||||
EOF_CODE,
|
||||
};
|
||||
AnalyzerHelper(Type helper_type, EmbeddedCode *code)
|
||||
: AnalyzerElement(HELPER),
|
||||
helper_type_(helper_type),
|
||||
code_(code) {}
|
||||
~AnalyzerHelper();
|
||||
|
||||
Type helper_type() const { return helper_type_; }
|
||||
|
||||
void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl);
|
||||
|
||||
EmbeddedCode *code() const { return code_; }
|
||||
|
||||
private:
|
||||
Type helper_type_;
|
||||
EmbeddedCode *code_;
|
||||
};
|
||||
|
||||
// The type and parameters of (uni-directional) flows of a connection.
|
||||
|
||||
class FlowField : public Field
|
||||
{
|
||||
public:
|
||||
FlowField(ID *flow_id, ParameterizedType *flow_type);
|
||||
void GenInitCode(Output *out, Env *env);
|
||||
};
|
||||
|
||||
class AnalyzerFlow : public AnalyzerElement
|
||||
{
|
||||
public:
|
||||
enum Direction { UP, DOWN };
|
||||
AnalyzerFlow(Direction dir, ID *type_id, ExprList *params);
|
||||
~AnalyzerFlow();
|
||||
|
||||
Direction dir() const { return dir_; }
|
||||
FlowField *flow_field() const { return flow_field_; }
|
||||
|
||||
FlowDecl *flow_decl();
|
||||
|
||||
private:
|
||||
Direction dir_;
|
||||
ID *type_id_;
|
||||
FlowField *flow_field_;
|
||||
FlowDecl *flow_decl_;
|
||||
};
|
||||
|
||||
#endif // pac_analyzer_h
|
|
@ -1,700 +0,0 @@
|
|||
#include "pac_attr.h"
|
||||
#include "pac_dataptr.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_exttype.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_number.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_utils.h"
|
||||
#include "pac_varfield.h"
|
||||
|
||||
#include "pac_array.h"
|
||||
|
||||
ArrayType::ArrayType(Type *elemtype, Expr *length)
|
||||
: Type(ARRAY), elemtype_(elemtype), length_(length)
|
||||
{
|
||||
init();
|
||||
|
||||
switch ( elemtype_->tot() )
|
||||
{
|
||||
case BUILTIN:
|
||||
case PARAMETERIZED:
|
||||
case STRING:
|
||||
case EXTERN:
|
||||
break;
|
||||
|
||||
case ARRAY:
|
||||
case CASE:
|
||||
case DUMMY:
|
||||
case EMPTY:
|
||||
case RECORD:
|
||||
case UNDEF:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::init()
|
||||
{
|
||||
arraylength_var_field_ = 0;
|
||||
elem_it_var_field_ = 0;
|
||||
elem_var_field_ = 0;
|
||||
elem_dataptr_var_field_ = 0;
|
||||
elem_input_var_field_ = 0;
|
||||
|
||||
elem_dataptr_until_expr_ = 0;
|
||||
|
||||
end_of_array_loop_label_ = "@@@";
|
||||
|
||||
vector_str_ = strfmt("vector<%s>", elemtype_->DataTypeStr().c_str());
|
||||
|
||||
datatype_str_ = strfmt("%s *", vector_str_.c_str());
|
||||
|
||||
attr_generic_until_expr_ = 0;
|
||||
attr_until_element_expr_ = 0;
|
||||
attr_until_input_expr_ = 0;
|
||||
}
|
||||
|
||||
ArrayType::~ArrayType()
|
||||
{
|
||||
delete arraylength_var_field_;
|
||||
delete elem_it_var_field_;
|
||||
delete elem_var_field_;
|
||||
delete elem_dataptr_var_field_;
|
||||
delete elem_input_var_field_;
|
||||
|
||||
delete elem_dataptr_until_expr_;
|
||||
}
|
||||
|
||||
Type *ArrayType::DoClone() const
|
||||
{
|
||||
Type *elemtype = elemtype_->Clone();
|
||||
if ( ! elemtype )
|
||||
return 0;
|
||||
return new ArrayType(elemtype, length_);
|
||||
}
|
||||
|
||||
bool ArrayType::DefineValueVar() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
string ArrayType::DataTypeStr() const
|
||||
{
|
||||
return datatype_str_;
|
||||
}
|
||||
|
||||
Type *ArrayType::ElementDataType() const
|
||||
{
|
||||
return elemtype_;
|
||||
}
|
||||
|
||||
string ArrayType::EvalElement(const string &array, const string &index) const
|
||||
{
|
||||
return strfmt("(*(%s))[%s]", array.c_str(), index.c_str());
|
||||
}
|
||||
|
||||
const ID *ArrayType::arraylength_var() const
|
||||
{
|
||||
return arraylength_var_field_ ? arraylength_var_field_->id() : 0;
|
||||
}
|
||||
|
||||
const ID *ArrayType::elem_it_var() const
|
||||
{
|
||||
return elem_it_var_field_ ? elem_it_var_field_->id() : 0;
|
||||
}
|
||||
|
||||
const ID *ArrayType::elem_var() const
|
||||
{
|
||||
return elem_var_field_ ? elem_var_field_->id() : 0;
|
||||
}
|
||||
|
||||
const ID *ArrayType::elem_dataptr_var() const
|
||||
{
|
||||
return elem_dataptr_var_field_ ? elem_dataptr_var_field_->id() : 0;
|
||||
}
|
||||
|
||||
const ID *ArrayType::elem_input_var() const
|
||||
{
|
||||
return elem_input_var_field_ ? elem_input_var_field_->id() : 0;
|
||||
}
|
||||
|
||||
void ArrayType::ProcessAttr(Attr *a)
|
||||
{
|
||||
Type::ProcessAttr(a);
|
||||
|
||||
switch ( a->type() )
|
||||
{
|
||||
case ATTR_RESTOFDATA:
|
||||
{
|
||||
if ( elemtype_->StaticSize(env()) != 1 )
|
||||
{
|
||||
throw Exception(elemtype_,
|
||||
"&restofdata can be applied"
|
||||
" to only byte arrays");
|
||||
}
|
||||
if ( length_ )
|
||||
{
|
||||
throw Exception(length_,
|
||||
"&restofdata cannot be applied"
|
||||
" to arrays with specified length");
|
||||
}
|
||||
attr_restofdata_ = true;
|
||||
// As the array automatically extends to the end of
|
||||
// data, we do not have to check boundary.
|
||||
SetBoundaryChecked();
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_RESTOFFLOW:
|
||||
attr_restofflow_ = true;
|
||||
// TODO: handle &restofflow
|
||||
break;
|
||||
|
||||
case ATTR_UNTIL:
|
||||
{
|
||||
bool ref_element = a->expr()->HasReference(element_macro_id);
|
||||
bool ref_input = a->expr()->HasReference(input_macro_id);
|
||||
if ( ref_element && ref_input )
|
||||
{
|
||||
throw Exception(a->expr(),
|
||||
"cannot reference both $element and $input "
|
||||
"in the same &until---please separate them.");
|
||||
}
|
||||
|
||||
if ( ref_element )
|
||||
{
|
||||
if ( attr_until_element_expr_ )
|
||||
{
|
||||
throw Exception(a->expr(),
|
||||
"multiple &until on $element");
|
||||
}
|
||||
attr_until_element_expr_ = a->expr();
|
||||
}
|
||||
else if ( ref_input )
|
||||
{
|
||||
if ( attr_until_input_expr_ )
|
||||
{
|
||||
throw Exception(a->expr(),
|
||||
"multiple &until on $input");
|
||||
}
|
||||
attr_until_input_expr_ = a->expr();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( attr_generic_until_expr_ )
|
||||
{
|
||||
throw Exception(a->expr(),
|
||||
"multiple &until condition");
|
||||
}
|
||||
attr_generic_until_expr_ = a->expr();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::Prepare(Env *env, int flags)
|
||||
{
|
||||
if ( flags & TO_BE_PARSED )
|
||||
{
|
||||
ID *arraylength_var = new ID(fmt("%s__arraylength", value_var()->Name()));
|
||||
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name()));
|
||||
ID *elem_it_var = new ID(fmt("%s__it", elem_var->Name()));
|
||||
|
||||
elem_var_field_ =
|
||||
new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
|
||||
AddField(elem_var_field_);
|
||||
|
||||
if ( incremental_parsing() )
|
||||
{
|
||||
arraylength_var_field_ =
|
||||
new PrivVarField(arraylength_var, extern_type_int->Clone());
|
||||
elem_it_var_field_ =
|
||||
new PrivVarField(elem_it_var, extern_type_int->Clone());
|
||||
|
||||
AddField(arraylength_var_field_);
|
||||
AddField(elem_it_var_field_);
|
||||
}
|
||||
else
|
||||
{
|
||||
arraylength_var_field_ =
|
||||
new TempVarField(arraylength_var, extern_type_int->Clone());
|
||||
elem_it_var_field_ =
|
||||
new TempVarField(elem_it_var, extern_type_int->Clone());
|
||||
|
||||
arraylength_var_field_->Prepare(env);
|
||||
elem_it_var_field_->Prepare(env);
|
||||
|
||||
// Add elem_dataptr_var only when not parsing incrementally
|
||||
ID *elem_dataptr_var =
|
||||
new ID(fmt("%s__dataptr", elem_var->Name()));
|
||||
elem_dataptr_var_field_ = new TempVarField(
|
||||
elem_dataptr_var,
|
||||
extern_type_const_byteptr->Clone());
|
||||
elem_dataptr_var_field_->Prepare(env);
|
||||
|
||||
// until(dataptr >= end_of_data)
|
||||
elem_dataptr_until_expr_ = new Expr(
|
||||
Expr::EXPR_GE,
|
||||
new Expr(elem_dataptr_var->clone()),
|
||||
new Expr(end_of_data->clone()));
|
||||
}
|
||||
|
||||
if ( attr_until_input_expr_ )
|
||||
{
|
||||
elemtype_->SetUntilCheck(this);
|
||||
}
|
||||
|
||||
end_of_array_loop_label_ = strfmt("end_of_%s", value_var()->Name());
|
||||
}
|
||||
|
||||
Type::Prepare(env, flags);
|
||||
}
|
||||
|
||||
void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
|
||||
{
|
||||
if ( env->Evaluated(arraylength_var()) )
|
||||
return;
|
||||
|
||||
if ( ! incremental_parsing() )
|
||||
{
|
||||
arraylength_var_field_->GenTempDecls(out_cc, env);
|
||||
arraylength_var_field_->GenInitCode(out_cc, env);
|
||||
}
|
||||
|
||||
if ( length_ )
|
||||
{
|
||||
out_cc->println("%s = %s;",
|
||||
env->LValue(arraylength_var()),
|
||||
length_->EvalExpr(out_cc, env));
|
||||
|
||||
env->SetEvaluated(arraylength_var());
|
||||
|
||||
// Check for overlong array length. We cap it at the
|
||||
// maximum data size as we won't store more elements.
|
||||
out_cc->println("if ( t_begin_of_data + %s > t_end_of_data + 1 )",
|
||||
env->LValue(arraylength_var()));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
out_cc->println("%s = t_end_of_data - t_begin_of_data + 1;",
|
||||
env->LValue(arraylength_var()));
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
|
||||
// Check negative array length
|
||||
out_cc->println("if ( %s < 0 )",
|
||||
env->LValue(arraylength_var()));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
out_cc->println("%s = 0;",
|
||||
env->LValue(arraylength_var()));
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
else if ( attr_restofdata_ )
|
||||
{
|
||||
ASSERT(elemtype_->StaticSize(env) == 1);
|
||||
out_cc->println("%s = (%s) - (%s);",
|
||||
env->LValue(arraylength_var()),
|
||||
env->RValue(end_of_data),
|
||||
data.ptr_expr());
|
||||
env->SetEvaluated(arraylength_var());
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::GenPubDecls(Output *out_h, Env *env)
|
||||
{
|
||||
Type::GenPubDecls(out_h, env);
|
||||
|
||||
if ( declared_as_type() )
|
||||
{
|
||||
out_h->println("int size() const { return %s ? %s->size() : 0; }",
|
||||
env->RValue(value_var()),
|
||||
env->RValue(value_var()));
|
||||
out_h->println("%s operator[](int index) const { BINPAC_ASSERT(%s); return (*%s)[index]; }",
|
||||
elemtype_->DataTypeConstRefStr().c_str(),
|
||||
env->RValue(value_var()),
|
||||
env->RValue(value_var()));
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::GenPrivDecls(Output *out_h, Env *env)
|
||||
{
|
||||
ASSERT(elem_var_field_->type() == elemtype_);
|
||||
ASSERT(elemtype_->value_var());
|
||||
Type::GenPrivDecls(out_h, env);
|
||||
}
|
||||
|
||||
void ArrayType::GenInitCode(Output *out_cc, Env *env)
|
||||
{
|
||||
// Do not initiate the array here
|
||||
// out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str());
|
||||
out_cc->println("%s = 0;", lvalue());
|
||||
|
||||
Type::GenInitCode(out_cc, env);
|
||||
if ( incremental_parsing() )
|
||||
{
|
||||
out_cc->println("%s = -1;",
|
||||
env->LValue(elem_it_var()));
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
|
||||
{
|
||||
Type::GenCleanUpCode(out_cc, env);
|
||||
if ( elemtype_->NeedsCleanUp() )
|
||||
{
|
||||
if ( ! elem_var_field_ )
|
||||
{
|
||||
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name()));
|
||||
elem_var_field_ =
|
||||
new ParseVarField(
|
||||
Field::NOT_CLASS_MEMBER,
|
||||
elem_var,
|
||||
elemtype_);
|
||||
elem_var_field_->Prepare(env);
|
||||
}
|
||||
|
||||
out_cc->println("if ( %s )", env->RValue(value_var()));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
out_cc->println("for ( int i = 0; i < (int) %s->size(); ++i )",
|
||||
env->RValue(value_var()));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
out_cc->println("%s %s = (*%s)[i];",
|
||||
elemtype_->DataTypeStr().c_str(),
|
||||
env->LValue(elem_var()),
|
||||
lvalue());
|
||||
elemtype_->GenCleanUpCode(out_cc, env);
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
out_cc->println("delete %s;", lvalue());
|
||||
}
|
||||
|
||||
string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length)
|
||||
{
|
||||
string array_str;
|
||||
|
||||
array_str = lvalue();
|
||||
if ( incremental_parsing() )
|
||||
{
|
||||
out_cc->println("if ( %s < 0 )",
|
||||
env->LValue(elem_it_var()));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
out_cc->println("// Initialize only once");
|
||||
out_cc->println("%s = 0;", env->LValue(elem_it_var()));
|
||||
}
|
||||
|
||||
out_cc->println("%s = new %s;",
|
||||
lvalue(), vector_str_.c_str());
|
||||
|
||||
if ( known_array_length )
|
||||
{
|
||||
out_cc->println("%s->reserve(%s);",
|
||||
lvalue(), env->RValue(arraylength_var()));
|
||||
}
|
||||
|
||||
if ( incremental_parsing() )
|
||||
{
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
||||
return array_str;
|
||||
}
|
||||
|
||||
void ArrayType::GenElementAssignment(Output *out_cc, Env *env,
|
||||
string const &array_str, bool use_vector)
|
||||
{
|
||||
// Assign the element
|
||||
if ( ! use_vector )
|
||||
{
|
||||
out_cc->println("%s[%s] = %s;",
|
||||
array_str.c_str(),
|
||||
env->LValue(elem_it_var()),
|
||||
env->LValue(elem_var()));
|
||||
}
|
||||
else
|
||||
{
|
||||
out_cc->println("%s->push_back(%s);",
|
||||
array_str.c_str(),
|
||||
env->LValue(elem_var()));
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||
const DataPtr& data, int flags)
|
||||
{
|
||||
GenArrayLength(out_cc, env, data);
|
||||
|
||||
// Otherwise these variables are declared as member variables
|
||||
if ( ! incremental_parsing() )
|
||||
{
|
||||
// Declare and initialize temporary variables
|
||||
elem_var_field_->GenInitCode(out_cc, env);
|
||||
elem_it_var_field_->GenTempDecls(out_cc, env);
|
||||
out_cc->println("%s = 0;", env->LValue(elem_it_var()));
|
||||
env->SetEvaluated(elem_it_var());
|
||||
}
|
||||
|
||||
/*
|
||||
If the input length can be determined without parsing
|
||||
individual elements, generate the boundary checking before
|
||||
parsing (unless in the case of incremental parsing).
|
||||
|
||||
There are two cases when the input length can be determined:
|
||||
1. The array has a static size;
|
||||
2. The array length can be computed before parsing and
|
||||
each element is of constant size.
|
||||
*/
|
||||
|
||||
bool compute_size_var = false;
|
||||
|
||||
if ( incremental_input() )
|
||||
{
|
||||
// Do not compute size_var on incremental input
|
||||
compute_size_var = false;
|
||||
|
||||
if ( ! incremental_parsing() &&
|
||||
( StaticSize(env) >= 0 ||
|
||||
( env->Evaluated(arraylength_var()) &&
|
||||
elemtype_->StaticSize(env) >= 0 ) ) )
|
||||
{
|
||||
GenBoundaryCheck(out_cc, env, data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
compute_size_var = AddSizeVar(out_cc, env);
|
||||
}
|
||||
|
||||
bool known_array_length = env->Evaluated(arraylength_var());
|
||||
string array_str = GenArrayInit(out_cc, env, known_array_length);
|
||||
|
||||
bool use_vector = true;
|
||||
|
||||
ASSERT(elem_it_var());
|
||||
|
||||
DataPtr elem_data(env, 0, 0);
|
||||
|
||||
if ( elem_dataptr_var() )
|
||||
{
|
||||
out_cc->println("const_byteptr %s = %s;",
|
||||
env->LValue(elem_dataptr_var()), data.ptr_expr());
|
||||
env->SetEvaluated(elem_dataptr_var());
|
||||
|
||||
elem_data = DataPtr(env, elem_dataptr_var(), 0);
|
||||
}
|
||||
|
||||
string for_condition = known_array_length ?
|
||||
strfmt("%s < %s",
|
||||
env->LValue(elem_it_var()),
|
||||
env->RValue(arraylength_var())) :
|
||||
"/* forever */";
|
||||
|
||||
out_cc->println("for (; %s; ++%s)",
|
||||
for_condition.c_str(),
|
||||
env->LValue(elem_it_var()));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
if ( attr_generic_until_expr_ )
|
||||
GenUntilCheck(out_cc, env, attr_generic_until_expr_, true);
|
||||
|
||||
if ( elem_dataptr_var() )
|
||||
GenUntilCheck(out_cc, env, elem_dataptr_until_expr_, false);
|
||||
|
||||
elemtype_->GenPreParsing(out_cc, env);
|
||||
elemtype_->GenParseCode(out_cc, env, elem_data, flags);
|
||||
|
||||
if ( incremental_parsing() )
|
||||
{
|
||||
out_cc->println("if ( ! %s )",
|
||||
elemtype_->parsing_complete(env).c_str());
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("goto %s;", kNeedMoreData);
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
||||
GenElementAssignment(out_cc, env, array_str, use_vector);
|
||||
|
||||
if ( elem_dataptr_var() )
|
||||
{
|
||||
out_cc->println("%s += %s;",
|
||||
env->LValue(elem_dataptr_var()),
|
||||
elemtype_->DataSize(0, env, elem_data).c_str());
|
||||
out_cc->println("BINPAC_ASSERT(%s <= %s);",
|
||||
env->RValue(elem_dataptr_var()),
|
||||
env->RValue(end_of_data));
|
||||
}
|
||||
|
||||
if ( attr_until_element_expr_ )
|
||||
GenUntilCheck(out_cc, env, attr_until_element_expr_, false);
|
||||
|
||||
if ( elemtype_->IsPointerType() )
|
||||
out_cc->println("%s = 0;", env->LValue(elem_var()));
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("%s: ;", end_of_array_loop_label_.c_str());
|
||||
out_cc->inc_indent();
|
||||
|
||||
if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) )
|
||||
{
|
||||
// Compute the data size
|
||||
out_cc->println("%s = %s - (%s);",
|
||||
env->LValue(size_var()),
|
||||
env->RValue(elem_dataptr_var()),
|
||||
data.ptr_expr());
|
||||
env->SetEvaluated(size_var());
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env)
|
||||
{
|
||||
ID *elem_input_var_id = new ID(
|
||||
fmt("%s__elem_input", value_var()->Name()));
|
||||
elem_input_var_field_ = new TempVarField(
|
||||
elem_input_var_id, extern_type_const_bytestring->Clone());
|
||||
elem_input_var_field_->Prepare(env);
|
||||
|
||||
out_cc->println("%s %s(%s, %s);",
|
||||
extern_type_const_bytestring->DataTypeStr().c_str(),
|
||||
env->LValue(elem_input_var()),
|
||||
env->RValue(begin_of_data),
|
||||
env->RValue(end_of_data));
|
||||
env->SetEvaluated(elem_input_var());
|
||||
|
||||
GenUntilCheck(out_cc, env, attr_until_input_expr_, true);
|
||||
}
|
||||
|
||||
void ArrayType::GenUntilCheck(Output *out_cc, Env *env,
|
||||
Expr *until_expr, bool delete_elem)
|
||||
{
|
||||
ASSERT(until_expr);
|
||||
|
||||
Env check_env(env, this);
|
||||
check_env.AddMacro(element_macro_id,
|
||||
new Expr(elem_var()->clone()));
|
||||
if ( elem_input_var() )
|
||||
{
|
||||
check_env.AddMacro(input_macro_id,
|
||||
new Expr(elem_input_var()->clone()));
|
||||
}
|
||||
|
||||
out_cc->println("// Check &until(%s)", until_expr->orig());
|
||||
out_cc->println("if ( %s )",
|
||||
until_expr->EvalExpr(out_cc, &check_env));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
if ( parsing_complete_var() )
|
||||
{
|
||||
out_cc->println("%s = true;",
|
||||
env->LValue(parsing_complete_var()));
|
||||
}
|
||||
|
||||
if ( elemtype_->IsPointerType() )
|
||||
{
|
||||
if ( delete_elem )
|
||||
elemtype_->GenCleanUpCode(out_cc, env);
|
||||
else
|
||||
out_cc->println("%s = 0;", env->LValue(elem_var()));
|
||||
}
|
||||
|
||||
out_cc->println("goto %s;", end_of_array_loop_label_.c_str());
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
||||
void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
|
||||
const DataPtr& data)
|
||||
{
|
||||
ASSERT(! incremental_input());
|
||||
DEBUG_MSG("Generating dynamic size for array `%s'\n",
|
||||
value_var()->Name());
|
||||
|
||||
int elem_w = elemtype_->StaticSize(env);
|
||||
if ( elem_w >= 0 &&
|
||||
! attr_until_element_expr_ &&
|
||||
! attr_until_input_expr_ &&
|
||||
( length_ || attr_restofdata_ ) )
|
||||
{
|
||||
// If the elements have a fixed size,
|
||||
// we only need to compute the number of elements
|
||||
bool compute_size_var = AddSizeVar(out_cc, env);
|
||||
ASSERT(compute_size_var);
|
||||
GenArrayLength(out_cc, env, data);
|
||||
ASSERT(env->Evaluated(arraylength_var()));
|
||||
out_cc->println("%s = %d * %s;",
|
||||
env->LValue(size_var()), elem_w, env->RValue(arraylength_var()));
|
||||
env->SetEvaluated(size_var());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise we need parse the array dynamically
|
||||
GenParseCode(out_cc, env, data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int ArrayType::StaticSize(Env *env) const
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
if ( ! length_ || ! length_->ConstFold(env, &num) )
|
||||
return -1;
|
||||
|
||||
int elem_w = elemtype_->StaticSize(env);
|
||||
if ( elem_w < 0 )
|
||||
return -1;
|
||||
|
||||
DEBUG_MSG("static size of %s:%s = %d * %d\n",
|
||||
decl_id()->Name(), lvalue(), elem_w, num);
|
||||
|
||||
return num * elem_w;
|
||||
}
|
||||
|
||||
void ArrayType::SetBoundaryChecked()
|
||||
{
|
||||
Type::SetBoundaryChecked();
|
||||
elemtype_->SetBoundaryChecked();
|
||||
}
|
||||
|
||||
void ArrayType::DoMarkIncrementalInput()
|
||||
{
|
||||
elemtype_->MarkIncrementalInput();
|
||||
}
|
||||
|
||||
bool ArrayType::RequiresAnalyzerContext()
|
||||
{
|
||||
return Type::RequiresAnalyzerContext() ||
|
||||
( length_ && length_->RequiresAnalyzerContext() ) ||
|
||||
elemtype_->RequiresAnalyzerContext();
|
||||
}
|
||||
|
||||
bool ArrayType::DoTraverse(DataDepVisitor *visitor)
|
||||
{
|
||||
if ( ! Type::DoTraverse(visitor) )
|
||||
return false;
|
||||
|
||||
if ( length_ && ! length_->Traverse(visitor) )
|
||||
return false;
|
||||
|
||||
if ( ! elemtype_->Traverse(visitor) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
#ifndef pac_array_h
|
||||
#define pac_array_h
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_type.h"
|
||||
|
||||
// Fixed-length array and variable length sequence with an ending pattern
|
||||
|
||||
class ArrayType : public Type
|
||||
{
|
||||
public:
|
||||
ArrayType(Type *arg_elemtype, Expr *arg_length = 0);
|
||||
~ArrayType();
|
||||
|
||||
bool DefineValueVar() const;
|
||||
string DataTypeStr() const;
|
||||
string DefaultValue() const { return "0"; }
|
||||
Type *ElementDataType() const;
|
||||
|
||||
string EvalElement(const string &array, const string &index) const;
|
||||
|
||||
void ProcessAttr(Attr *a);
|
||||
|
||||
void Prepare(Env *env, int flags);
|
||||
|
||||
void GenPubDecls(Output *out, Env *env);
|
||||
void GenPrivDecls(Output *out, Env *env);
|
||||
|
||||
void GenInitCode(Output *out, Env *env);
|
||||
void GenCleanUpCode(Output *out, Env *env);
|
||||
|
||||
int StaticSize(Env *env) const;
|
||||
|
||||
void SetBoundaryChecked();
|
||||
void GenUntilInputCheck(Output *out_cc, Env *env);
|
||||
|
||||
bool IsPointerType() const { return true; }
|
||||
|
||||
protected:
|
||||
void init();
|
||||
|
||||
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
|
||||
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
|
||||
void GenArrayLength(Output *out_cc, Env *env, const DataPtr& data);
|
||||
string GenArrayInit(Output *out_cc, Env *env, bool known_array_length);
|
||||
void GenElementAssignment(Output *out_cc, Env *env,
|
||||
string const &array_str, bool use_vector);
|
||||
void GenUntilCheck(Output *out_cc, Env *env,
|
||||
Expr *until_condition, bool delete_elem);
|
||||
|
||||
bool ByteOrderSensitive() const
|
||||
{
|
||||
return elemtype_->RequiresByteOrder();
|
||||
}
|
||||
bool RequiresAnalyzerContext();
|
||||
|
||||
Type *DoClone() const;
|
||||
|
||||
void DoMarkIncrementalInput();
|
||||
|
||||
const ID *arraylength_var() const;
|
||||
const ID *elem_it_var() const;
|
||||
const ID *elem_var() const;
|
||||
const ID *elem_dataptr_var() const;
|
||||
const ID *elem_input_var() const;
|
||||
|
||||
protected:
|
||||
bool DoTraverse(DataDepVisitor *visitor);
|
||||
|
||||
private:
|
||||
Type *elemtype_;
|
||||
Expr *length_;
|
||||
|
||||
string vector_str_;
|
||||
string datatype_str_;
|
||||
string end_of_array_loop_label_;
|
||||
|
||||
Field *arraylength_var_field_;
|
||||
Field *elem_it_var_field_;
|
||||
Field *elem_var_field_;
|
||||
Field *elem_dataptr_var_field_;
|
||||
Field *elem_input_var_field_;
|
||||
|
||||
// This does not come from &until, but is internally generated
|
||||
Expr *elem_dataptr_until_expr_;
|
||||
|
||||
Expr *attr_generic_until_expr_;
|
||||
Expr *attr_until_element_expr_;
|
||||
Expr *attr_until_input_expr_;
|
||||
};
|
||||
|
||||
#endif // pac_array_h
|
|
@ -1,57 +0,0 @@
|
|||
#include "pac_attr.h"
|
||||
#include "pac_expr.h"
|
||||
|
||||
bool Attr::DoTraverse(DataDepVisitor *visitor)
|
||||
{
|
||||
if ( expr_ && ! expr_->Traverse(visitor) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Attr::RequiresAnalyzerContext() const
|
||||
{
|
||||
return (expr_ && expr_->RequiresAnalyzerContext());
|
||||
}
|
||||
|
||||
void Attr::init()
|
||||
{
|
||||
expr_ = 0;
|
||||
seqend_ = 0;
|
||||
}
|
||||
|
||||
Attr::Attr(AttrType type)
|
||||
: DataDepElement(DataDepElement::ATTR)
|
||||
{
|
||||
type_ = type;
|
||||
init();
|
||||
}
|
||||
|
||||
Attr::Attr(AttrType type, Expr *expr)
|
||||
: DataDepElement(DataDepElement::ATTR)
|
||||
{
|
||||
type_ = type;
|
||||
init();
|
||||
expr_ = expr;
|
||||
}
|
||||
|
||||
Attr::Attr(AttrType type, ExprList *exprlist)
|
||||
: DataDepElement(DataDepElement::ATTR)
|
||||
{
|
||||
type_ = type;
|
||||
init();
|
||||
expr_ = new Expr(exprlist);
|
||||
}
|
||||
|
||||
Attr::Attr(AttrType type, SeqEnd *seqend)
|
||||
: DataDepElement(DataDepElement::ATTR)
|
||||
{
|
||||
type_ = type;
|
||||
init();
|
||||
seqend_ = seqend;
|
||||
}
|
||||
|
||||
LetAttr::LetAttr(FieldList *letfields)
|
||||
: Attr(ATTR_LET)
|
||||
{
|
||||
letfields_ = letfields;
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
#ifndef pac_attr_h
|
||||
#define pac_attr_h
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_datadep.h"
|
||||
|
||||
enum AttrType {
|
||||
ATTR_BYTEORDER,
|
||||
ATTR_CHECK,
|
||||
ATTR_CHUNKED,
|
||||
ATTR_EXPORTSOURCEDATA,
|
||||
ATTR_IF,
|
||||
ATTR_LENGTH,
|
||||
ATTR_LET,
|
||||
ATTR_LINEBREAKER,
|
||||
ATTR_MULTILINE,
|
||||
ATTR_ONELINE,
|
||||
ATTR_REFCOUNT,
|
||||
ATTR_REQUIRES,
|
||||
ATTR_RESTOFDATA,
|
||||
ATTR_RESTOFFLOW,
|
||||
ATTR_TRANSIENT,
|
||||
ATTR_UNTIL,
|
||||
};
|
||||
|
||||
class Attr : public Object, public DataDepElement
|
||||
{
|
||||
public:
|
||||
Attr(AttrType type);
|
||||
Attr(AttrType type, Expr *expr);
|
||||
Attr(AttrType type, ExprList *exprlist);
|
||||
Attr(AttrType type, SeqEnd *seqend);
|
||||
|
||||
AttrType type() const { return type_; }
|
||||
Expr *expr() const { return expr_; }
|
||||
SeqEnd *seqend() const { return seqend_; }
|
||||
|
||||
bool RequiresAnalyzerContext() const;
|
||||
|
||||
protected:
|
||||
bool DoTraverse(DataDepVisitor *visitor);
|
||||
|
||||
protected:
|
||||
void init();
|
||||
|
||||
AttrType type_;
|
||||
Expr *expr_;
|
||||
SeqEnd *seqend_;
|
||||
};
|
||||
|
||||
class LetAttr : public Attr
|
||||
{
|
||||
public:
|
||||
LetAttr(FieldList *letfields);
|
||||
FieldList *letfields() const { return letfields_; }
|
||||
|
||||
private:
|
||||
FieldList *letfields_;
|
||||
};
|
||||
|
||||
#endif // pac_attr_h
|
|
@ -1,144 +0,0 @@
|
|||
#include "pac_btype.h"
|
||||
#include "pac_dataptr.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
|
||||
Type *BuiltInType::DoClone() const
|
||||
{
|
||||
return new BuiltInType(bit_type());
|
||||
}
|
||||
|
||||
bool BuiltInType::IsNumericType() const
|
||||
{
|
||||
BITType t = bit_type();
|
||||
return (t == INT8 || t == INT16 || t == INT32 ||
|
||||
t == UINT8 || t == UINT16 || t == UINT32);
|
||||
}
|
||||
|
||||
bool BuiltInType::CompatibleBuiltInTypes(BuiltInType *type1,
|
||||
BuiltInType *type2)
|
||||
{
|
||||
return type1->IsNumericType() && type2->IsNumericType();
|
||||
}
|
||||
|
||||
static const char* basic_pactype_name[] = {
|
||||
# define TYPE_DEF(name, pactype, ctype, size) pactype,
|
||||
# include "pac_type.def"
|
||||
# undef TYPE_DEF
|
||||
0,
|
||||
};
|
||||
|
||||
void BuiltInType::static_init()
|
||||
{
|
||||
for ( int bit_type = 0; basic_pactype_name[bit_type]; ++bit_type )
|
||||
{
|
||||
Type::AddPredefinedType(
|
||||
basic_pactype_name[bit_type],
|
||||
new BuiltInType((BITType) bit_type));
|
||||
}
|
||||
}
|
||||
|
||||
int BuiltInType::LookUpByName(const char* name)
|
||||
{
|
||||
ASSERT(0);
|
||||
for ( int i = 0; basic_pactype_name[i]; ++i )
|
||||
if ( strcmp(basic_pactype_name[i], name) == 0 )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char* basic_ctype_name[] = {
|
||||
# define TYPE_DEF(name, pactype, ctype, size) ctype,
|
||||
# include "pac_type.def"
|
||||
# undef TYPE_DEF
|
||||
0,
|
||||
};
|
||||
|
||||
bool BuiltInType::DefineValueVar() const
|
||||
{
|
||||
return bit_type_ != EMPTY;
|
||||
}
|
||||
|
||||
string BuiltInType::DataTypeStr() const
|
||||
{
|
||||
return basic_ctype_name[bit_type_];
|
||||
}
|
||||
|
||||
int BuiltInType::StaticSize(Env* /* env */) const
|
||||
{
|
||||
static const size_t basic_type_size[] =
|
||||
{
|
||||
# define TYPE_DEF(name, pactype, ctype, size) size,
|
||||
# include "pac_type.def"
|
||||
# undef TYPE_DEF
|
||||
};
|
||||
|
||||
return basic_type_size[bit_type_];
|
||||
}
|
||||
|
||||
void BuiltInType::DoMarkIncrementalInput()
|
||||
{
|
||||
if ( bit_type_ == EMPTY )
|
||||
return;
|
||||
Type::DoMarkIncrementalInput();
|
||||
}
|
||||
|
||||
void BuiltInType::GenInitCode(Output* out_cc, Env* env)
|
||||
{
|
||||
if ( bit_type_ != EMPTY )
|
||||
out_cc->println("%s = 0;", env->LValue(value_var()));
|
||||
Type::GenInitCode(out_cc, env);
|
||||
}
|
||||
|
||||
void BuiltInType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data)
|
||||
{
|
||||
/* should never be called */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
void BuiltInType::DoGenParseCode(Output* out_cc, Env* env,
|
||||
const DataPtr& data, int flags)
|
||||
{
|
||||
if ( bit_type_ == EMPTY )
|
||||
return;
|
||||
|
||||
// There is no need to generate the size variable
|
||||
// out_cc->println("%s = sizeof(%s);", size_var(), DataTypeStr().c_str());
|
||||
|
||||
GenBoundaryCheck(out_cc, env, data);
|
||||
|
||||
if ( anonymous_value_var() )
|
||||
return;
|
||||
|
||||
switch ( bit_type_ )
|
||||
{
|
||||
case EMPTY:
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
case INT8:
|
||||
case UINT8:
|
||||
out_cc->println("%s = *((%s const *) (%s));",
|
||||
lvalue(), DataTypeStr().c_str(), data.ptr_expr());
|
||||
break;
|
||||
case INT16:
|
||||
case UINT16:
|
||||
case INT32:
|
||||
case UINT32:
|
||||
#if 0
|
||||
out_cc->println("%s = UnMarshall<%s>(%s, %s);",
|
||||
lvalue(),
|
||||
DataTypeStr().c_str(),
|
||||
data.ptr_expr(),
|
||||
EvalByteOrder(out_cc, env).c_str());
|
||||
#else
|
||||
out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));",
|
||||
lvalue(),
|
||||
EvalByteOrder(out_cc, env).c_str(),
|
||||
DataTypeStr().c_str(),
|
||||
data.ptr_expr());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#ifndef pac_btype_h
|
||||
#define pac_btype_h
|
||||
|
||||
#include "pac_type.h"
|
||||
|
||||
class BuiltInType : public Type
|
||||
{
|
||||
public:
|
||||
enum BITType {
|
||||
# define TYPE_DEF(name, pactype, ctype, size) name,
|
||||
# include "pac_type.def"
|
||||
# undef TYPE_DEF
|
||||
};
|
||||
|
||||
static int LookUpByName(const char *name);
|
||||
|
||||
BuiltInType(BITType bit_type)
|
||||
: Type(bit_type == BuiltInType::EMPTY ? Type::EMPTY : BUILTIN),
|
||||
bit_type_(bit_type) {}
|
||||
|
||||
BITType bit_type() const { return bit_type_; }
|
||||
|
||||
bool IsNumericType() const;
|
||||
|
||||
bool DefineValueVar() const;
|
||||
string DataTypeStr() const;
|
||||
string DefaultValue() const { return "0"; }
|
||||
|
||||
int StaticSize(Env *env) const;
|
||||
|
||||
bool IsPointerType() const { return false; }
|
||||
|
||||
bool ByteOrderSensitive() const { return StaticSize(0) >= 2; }
|
||||
|
||||
void GenInitCode(Output *out_cc, Env *env);
|
||||
|
||||
void DoMarkIncrementalInput();
|
||||
|
||||
protected:
|
||||
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
|
||||
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
|
||||
Type *DoClone() const;
|
||||
|
||||
BITType bit_type_;
|
||||
|
||||
public:
|
||||
static void static_init();
|
||||
static bool CompatibleBuiltInTypes(BuiltInType *type1,
|
||||
BuiltInType *type2);
|
||||
};
|
||||
|
||||
#endif // pac_btype_h
|
|
@ -1,391 +0,0 @@
|
|||
#include "pac_exception.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_exttype.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_typedecl.h"
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include "pac_case.h"
|
||||
|
||||
CaseType::CaseType(Expr* index_expr, CaseFieldList* cases)
|
||||
: Type(CASE), index_expr_(index_expr), cases_(cases)
|
||||
{
|
||||
index_var_ = 0;
|
||||
foreach(i, CaseFieldList, cases_)
|
||||
AddField(*i);
|
||||
}
|
||||
|
||||
CaseType::~CaseType()
|
||||
{
|
||||
delete index_var_;
|
||||
delete index_expr_;
|
||||
delete cases_;
|
||||
}
|
||||
|
||||
void CaseType::AddCaseField(CaseField *f)
|
||||
{
|
||||
// All fields must be added before Prepare()
|
||||
ASSERT(!env());
|
||||
|
||||
AddField(f);
|
||||
cases_->push_back(f);
|
||||
}
|
||||
|
||||
bool CaseType::DefineValueVar() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string CaseType::DataTypeStr() const
|
||||
{
|
||||
ASSERT(type_decl());
|
||||
return strfmt("%s *", type_decl()->class_name().c_str());
|
||||
}
|
||||
|
||||
Type *CaseType::ValueType() const
|
||||
{
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
return c->type();
|
||||
}
|
||||
ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
string CaseType::DefaultValue() const
|
||||
{
|
||||
return ValueType()->DefaultValue();
|
||||
}
|
||||
|
||||
void CaseType::Prepare(Env* env, int flags)
|
||||
{
|
||||
ASSERT(flags & TO_BE_PARSED);
|
||||
|
||||
index_var_ = new ID(fmt("%s_case_index", value_var()->Name()));
|
||||
env->AddID(index_var_, MEMBER_VAR, extern_type_int);
|
||||
|
||||
// Sort the cases_ to put the default case at the end of the list
|
||||
CaseFieldList::iterator default_case_it =
|
||||
cases_->end(); // to avoid warning
|
||||
CaseField *default_case = 0;
|
||||
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
if ( ! c->index() )
|
||||
{
|
||||
if ( default_case )
|
||||
throw Exception(c, "duplicate default case");
|
||||
default_case_it = i;
|
||||
default_case = c;
|
||||
}
|
||||
}
|
||||
if ( default_case )
|
||||
{
|
||||
cases_->erase(default_case_it);
|
||||
cases_->push_back(default_case);
|
||||
}
|
||||
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
c->set_index_var(index_var_);
|
||||
c->set_case_type(this);
|
||||
}
|
||||
|
||||
Type::Prepare(env, flags);
|
||||
}
|
||||
|
||||
void CaseType::GenPrivDecls(Output* out_h, Env* env)
|
||||
{
|
||||
out_h->println("int %s;", env->LValue(index_var_));
|
||||
Type::GenPrivDecls(out_h, env);
|
||||
}
|
||||
|
||||
void CaseType::GenPubDecls(Output* out_h, Env* env)
|
||||
{
|
||||
out_h->println("int %s const { return %s; }",
|
||||
env->RValue(index_var_), env->LValue(index_var_));
|
||||
Type::GenPubDecls(out_h, env);
|
||||
}
|
||||
|
||||
void CaseType::GenInitCode(Output* out_cc, Env* env)
|
||||
{
|
||||
out_cc->println("%s = -1;", env->LValue(index_var_));
|
||||
Type::GenInitCode(out_cc, env);
|
||||
}
|
||||
|
||||
void CaseType::GenCleanUpCode(Output* out_cc, Env* env)
|
||||
{
|
||||
Type::GenCleanUpCode(out_cc, env);
|
||||
|
||||
env->set_in_branch(true);
|
||||
out_cc->println("switch ( %s )", env->RValue(index_var_));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
c->GenCleanUpCode(out_cc, env);
|
||||
}
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
env->set_in_branch(false);
|
||||
}
|
||||
|
||||
void CaseType::DoGenParseCode(Output* out_cc, Env* env,
|
||||
const DataPtr& data, int flags)
|
||||
{
|
||||
if ( StaticSize(env) >= 0 )
|
||||
GenBoundaryCheck(out_cc, env, data);
|
||||
|
||||
bool compute_size_var = false;
|
||||
|
||||
if ( ! incremental_input() )
|
||||
compute_size_var = AddSizeVar(out_cc, env);
|
||||
|
||||
out_cc->println("%s = %s;",
|
||||
env->LValue(index_var_), index_expr_->EvalExpr(out_cc, env));
|
||||
env->SetEvaluated(index_var_);
|
||||
|
||||
env->set_in_branch(true);
|
||||
out_cc->println("switch ( %s )", env->RValue(index_var_));
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
bool has_default_case = false;
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
c->GenParseCode(out_cc, env, data,
|
||||
compute_size_var ? size_var() : 0);
|
||||
if ( c->IsDefaultCase() )
|
||||
has_default_case = true;
|
||||
}
|
||||
|
||||
if ( ! has_default_case )
|
||||
{
|
||||
out_cc->println("default:");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("throw ExceptionInvalidCaseIndex(\"%s\", %s);",
|
||||
decl_id()->Name(), env->RValue(index_var_));
|
||||
out_cc->println("break;");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
env->set_in_branch(false);
|
||||
|
||||
if ( compute_size_var )
|
||||
env->SetEvaluated(size_var());
|
||||
}
|
||||
|
||||
void CaseType::GenDynamicSize(Output* out_cc, Env* env,
|
||||
const DataPtr& data)
|
||||
{
|
||||
GenParseCode(out_cc, env, data, 0);
|
||||
}
|
||||
|
||||
int CaseType::StaticSize(Env* env) const
|
||||
{
|
||||
int static_w = -1;
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
int w = c->StaticSize(env);
|
||||
if ( w < 0 || ( static_w >= 0 && w != static_w ) )
|
||||
return -1;
|
||||
static_w = w;
|
||||
}
|
||||
return static_w;
|
||||
}
|
||||
|
||||
void CaseType::SetBoundaryChecked()
|
||||
{
|
||||
Type::SetBoundaryChecked();
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
c->SetBoundaryChecked();
|
||||
}
|
||||
}
|
||||
|
||||
void CaseType::DoMarkIncrementalInput()
|
||||
{
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
c->type()->MarkIncrementalInput();
|
||||
}
|
||||
}
|
||||
|
||||
bool CaseType::ByteOrderSensitive() const
|
||||
{
|
||||
foreach (i, CaseFieldList, cases_)
|
||||
{
|
||||
CaseField *c = *i;
|
||||
if ( c->RequiresByteOrder() )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
CaseField::CaseField(ExprList* index, ID* id, Type* type)
|
||||
: Field(CASE_FIELD,
|
||||
TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
id, type),
|
||||
index_(index)
|
||||
{
|
||||
ASSERT(type_);
|
||||
type_->set_value_var(id, MEMBER_VAR);
|
||||
case_type_ = 0;
|
||||
}
|
||||
|
||||
CaseField::~CaseField()
|
||||
{
|
||||
delete_list(ExprList, index_);
|
||||
}
|
||||
|
||||
void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env)
|
||||
{
|
||||
if ( index_list )
|
||||
{
|
||||
foreach(i, ExprList, index_list)
|
||||
{
|
||||
Expr *index_expr = *i;
|
||||
int index_const;
|
||||
|
||||
if ( ! index_expr->ConstFold(env, &index_const) )
|
||||
throw ExceptionNonConstExpr(index_expr);
|
||||
out_cc->println("case %d:", index_const);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out_cc->println("default:");
|
||||
}
|
||||
}
|
||||
|
||||
void CaseField::Prepare(Env* env)
|
||||
{
|
||||
ASSERT(index_var_);
|
||||
Field::Prepare(env);
|
||||
}
|
||||
|
||||
void CaseField::GenPubDecls(Output* out_h, Env* env)
|
||||
{
|
||||
if ( ! ((flags_ & PUBLIC_READABLE) && (flags_ & CLASS_MEMBER)) )
|
||||
return;
|
||||
|
||||
// Skip type "empty"
|
||||
if ( type_->DataTypeStr().empty() )
|
||||
return;
|
||||
|
||||
out_h->println("%s %s const",
|
||||
type_->DataTypeConstRefStr().c_str(), env->RValue(id_));
|
||||
|
||||
out_h->inc_indent();
|
||||
out_h->println("{");
|
||||
|
||||
if ( ! index_ )
|
||||
out_h->println("return %s;", lvalue());
|
||||
else
|
||||
{
|
||||
out_h->println("switch ( %s )", env->RValue(index_var_));
|
||||
out_h->inc_indent();
|
||||
out_h->println("{");
|
||||
GenCaseStr(index_, out_h, env);
|
||||
out_h->inc_indent();
|
||||
out_h->println("break; // OK");
|
||||
out_h->dec_indent();
|
||||
|
||||
out_h->println("default:");
|
||||
out_h->inc_indent();
|
||||
out_h->println("throw ExceptionInvalidCase(\"%s\", %s, \"%s\");",
|
||||
id_->LocName(),
|
||||
env->RValue(index_var_),
|
||||
OrigExprList(index_).c_str());
|
||||
out_h->println("break;");
|
||||
out_h->dec_indent();
|
||||
|
||||
out_h->println("}");
|
||||
out_h->dec_indent();
|
||||
|
||||
out_h->println("return %s;", lvalue());
|
||||
}
|
||||
|
||||
out_h->println("}");
|
||||
out_h->dec_indent();
|
||||
}
|
||||
|
||||
void CaseField::GenInitCode(Output* out_cc, Env* env)
|
||||
{
|
||||
// GenCaseStr(index_, out_cc, env);
|
||||
// out_cc->inc_indent();
|
||||
// out_cc->println("{");
|
||||
// out_cc->println("// Initialize \"%s\"", id_->Name());
|
||||
type_->GenInitCode(out_cc, env);
|
||||
// out_cc->println("}");
|
||||
// out_cc->println("break;");
|
||||
// out_cc->dec_indent();
|
||||
}
|
||||
|
||||
void CaseField::GenCleanUpCode(Output* out_cc, Env* env)
|
||||
{
|
||||
GenCaseStr(index_, out_cc, env);
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("// Clean up \"%s\"", id_->Name());
|
||||
out_cc->println("{");
|
||||
if ( ! anonymous_field() )
|
||||
type_->GenCleanUpCode(out_cc, env);
|
||||
out_cc->println("}");
|
||||
out_cc->println("break;");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
||||
void CaseField::GenParseCode(Output* out_cc, Env* env,
|
||||
const DataPtr& data, const ID* size_var)
|
||||
{
|
||||
GenCaseStr(index_, out_cc, env);
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("// Parse \"%s\"", id_->Name());
|
||||
out_cc->println("{");
|
||||
|
||||
{
|
||||
Env case_env(env, this);
|
||||
Env *env = &case_env;
|
||||
|
||||
type_->GenPreParsing(out_cc, env);
|
||||
type_->GenParseCode(out_cc, env, data, 0);
|
||||
if ( size_var )
|
||||
{
|
||||
out_cc->println("%s = %s;",
|
||||
env->LValue(size_var),
|
||||
type_->DataSize(out_cc, env, data).c_str());
|
||||
}
|
||||
if ( type_->incremental_input() )
|
||||
{
|
||||
ASSERT(case_type()->parsing_complete_var());
|
||||
out_cc->println("%s = %s;",
|
||||
env->LValue(case_type()->parsing_complete_var()),
|
||||
env->RValue(type_->parsing_complete_var()));
|
||||
}
|
||||
out_cc->println("}");
|
||||
}
|
||||
|
||||
out_cc->println("break;");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
||||
bool CaseField::DoTraverse(DataDepVisitor *visitor)
|
||||
{
|
||||
return Field::DoTraverse(visitor) &&
|
||||
type()->Traverse(visitor);
|
||||
}
|
||||
|
||||
bool CaseField::RequiresAnalyzerContext() const
|
||||
{
|
||||
return Field::RequiresAnalyzerContext() ||
|
||||
type()->RequiresAnalyzerContext();
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
#ifndef pac_case_h
|
||||
#define pac_case_h
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_field.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_type.h"
|
||||
|
||||
class CaseType : public Type
|
||||
{
|
||||
public:
|
||||
CaseType(Expr *index, CaseFieldList *cases);
|
||||
~CaseType();
|
||||
|
||||
void AddCaseField(CaseField *f);
|
||||
|
||||
bool DefineValueVar() const;
|
||||
string DataTypeStr() const;
|
||||
string DefaultValue() const;
|
||||
|
||||
void Prepare(Env *env, int flags);
|
||||
|
||||
void GenPubDecls(Output *out, Env *env);
|
||||
void GenPrivDecls(Output *out, Env *env);
|
||||
|
||||
void GenInitCode(Output *out, Env *env);
|
||||
void GenCleanUpCode(Output *out, Env *env);
|
||||
|
||||
int StaticSize(Env *env) const;
|
||||
|
||||
void SetBoundaryChecked();
|
||||
|
||||
Type *ValueType() const;
|
||||
|
||||
bool IsPointerType() const { return ValueType()->IsPointerType(); }
|
||||
|
||||
protected:
|
||||
void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags);
|
||||
void GenDynamicSize(Output *out, Env *env, const DataPtr& data);
|
||||
Type *DoClone() const { return 0; }
|
||||
void DoMarkIncrementalInput();
|
||||
|
||||
bool ByteOrderSensitive() const;
|
||||
|
||||
Expr *index_expr_;
|
||||
ID *index_var_;
|
||||
CaseFieldList *cases_;
|
||||
|
||||
typedef map<const ID*, CaseField*, ID_ptr_cmp> member_map_t;
|
||||
member_map_t member_map_;
|
||||
};
|
||||
|
||||
class CaseField : public Field
|
||||
{
|
||||
public:
|
||||
CaseField(ExprList *index, ID *id, Type *type);
|
||||
~CaseField();
|
||||
|
||||
CaseType *case_type() const { return case_type_; }
|
||||
void set_case_type(CaseType *t) { case_type_ = t; }
|
||||
|
||||
ExprList *index() const { return index_; }
|
||||
|
||||
const char *lvalue() const { return type_->lvalue(); }
|
||||
|
||||
const char *CaseStr(Env *env);
|
||||
void set_index_var(const ID *var) { index_var_ = var; }
|
||||
|
||||
void Prepare(Env *env);
|
||||
|
||||
void GenPubDecls(Output *out, Env *env);
|
||||
|
||||
void GenInitCode(Output *out, Env *env);
|
||||
void GenCleanUpCode(Output *out, Env *env);
|
||||
void GenParseCode(Output *out, Env *env,
|
||||
const DataPtr& data, const ID *size_var);
|
||||
|
||||
int StaticSize(Env *env) const { return type_->StaticSize(env); }
|
||||
|
||||
bool IsDefaultCase() const { return ! index_; }
|
||||
void SetBoundaryChecked() { type_->SetBoundaryChecked(); }
|
||||
|
||||
bool RequiresByteOrder() const { return type_->RequiresByteOrder(); }
|
||||
bool RequiresAnalyzerContext() const;
|
||||
|
||||
protected:
|
||||
bool DoTraverse(DataDepVisitor *visitor);
|
||||
|
||||
protected:
|
||||
CaseType *case_type_;
|
||||
ExprList *index_;
|
||||
const ID *index_var_;
|
||||
};
|
||||
|
||||
// Generate a list of "case X:" lines from index_list. Each index
|
||||
// expression must be constant foldable.
|
||||
void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env);
|
||||
|
||||
#endif // pac_case_h
|
|
@ -1,81 +0,0 @@
|
|||
#ifndef pac_cclass_h
|
||||
#define pac_cclass_h
|
||||
|
||||
class CClass;
|
||||
class CClassMember;
|
||||
class CClassMethod;
|
||||
class CType;
|
||||
class CVariable;
|
||||
|
||||
typedef vector<CClassMember *> CClassMemberList;
|
||||
typedef vector<CClassMethod *> CClassMethodList;
|
||||
typedef vector<CVariable *> CVariableList;
|
||||
|
||||
#include "pac_common.h"
|
||||
|
||||
// Represents a C++ class.
|
||||
//
|
||||
// For now we adopt a simple model:
|
||||
//
|
||||
// 1. All members have a protected member variable "name_" and a
|
||||
// public constant access method "name()".
|
||||
//
|
||||
// 2. All methods are public.
|
||||
//
|
||||
// 3. We do not check repeated names.
|
||||
|
||||
class CClass
|
||||
{
|
||||
public:
|
||||
CClass(const string &class_name);
|
||||
|
||||
void AddMember(CClassMember *member);
|
||||
void AddMethod(CClassMember *method);
|
||||
|
||||
void GenForwardDeclaration(Output *out_h);
|
||||
void GenCode(Output *out_h, Output *out_cc);
|
||||
|
||||
protected:
|
||||
string class_name_;
|
||||
CClassMemberList *members_;
|
||||
CClassMethodList *methods_;
|
||||
};
|
||||
|
||||
class CVariable
|
||||
{
|
||||
public:
|
||||
CClassMember(const string &name, CType *type);
|
||||
|
||||
string name() const { return name_; }
|
||||
CType *type() const { return type_; }
|
||||
|
||||
protected:
|
||||
string name_;
|
||||
CType *type_;
|
||||
};
|
||||
|
||||
class CClassMember
|
||||
{
|
||||
public:
|
||||
CClassMember(CVariable *var);
|
||||
void GenCode(Output *out_h, Output *out_cc);
|
||||
|
||||
string decl() const;
|
||||
|
||||
protected:
|
||||
CVariable *var_;
|
||||
};
|
||||
|
||||
class CClassMethod
|
||||
{
|
||||
public:
|
||||
CClassMethod(CVariable *var, CVariableList *params);
|
||||
|
||||
string decl() const;
|
||||
|
||||
protected:
|
||||
CVariable *var_;
|
||||
CVariableList *params_;
|
||||
};
|
||||
|
||||
#endif // pac_cclass_h
|
|
@ -1,134 +0,0 @@
|
|||
#ifndef pac_common_h
|
||||
#define pac_common_h
|
||||
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern bool FLAGS_pac_debug;
|
||||
extern vector<string> FLAGS_include_directories;
|
||||
extern string input_filename;
|
||||
extern int line_number;
|
||||
|
||||
// Definition of class Object, which is the base class for all objects
|
||||
// representing language elements -- identifiers, types, expressions,
|
||||
// etc.
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
Object()
|
||||
{
|
||||
filename = input_filename;
|
||||
line_num = line_number;
|
||||
location = strfmt("%s:%d", filename.c_str(), line_number);
|
||||
}
|
||||
|
||||
~Object()
|
||||
{
|
||||
}
|
||||
|
||||
const char* Location() const { return location.c_str(); }
|
||||
|
||||
protected:
|
||||
string filename;
|
||||
int line_num;
|
||||
string location;
|
||||
};
|
||||
|
||||
class ActionParam;
|
||||
class ActionParamType;
|
||||
class AnalyzerAction;
|
||||
class AnalyzerContextDecl;
|
||||
class AnalyzerDecl;
|
||||
class AnalyzerElement;
|
||||
class ArrayType;
|
||||
class Attr;
|
||||
class CClass;
|
||||
class CType;
|
||||
class ConstString;
|
||||
class CaseExpr;
|
||||
class CaseField;
|
||||
class ContextField;
|
||||
class DataPtr;
|
||||
class Decl;
|
||||
class EmbeddedCode;
|
||||
class Enum;
|
||||
class Env;
|
||||
class ExternType;
|
||||
class Expr;
|
||||
class Field;
|
||||
class Function;
|
||||
class InputBuffer;
|
||||
class LetDef;
|
||||
class LetField;
|
||||
class ID;
|
||||
class Number;
|
||||
class Output;
|
||||
class PacPrimitive;
|
||||
class Param;
|
||||
class ParameterizedType;
|
||||
class RecordType;
|
||||
class RecordField;
|
||||
class RecordDataField;
|
||||
class RecordPaddingField;
|
||||
class RegEx;
|
||||
class SeqEnd;
|
||||
class StateVar;
|
||||
class Type;
|
||||
class TypeDecl;
|
||||
class WithInputField;
|
||||
|
||||
// The ID of the current declaration.
|
||||
extern const ID* current_decl_id;
|
||||
|
||||
typedef vector<ActionParam*> ActionParamList;
|
||||
typedef vector<AnalyzerAction*> AnalyzerActionList;
|
||||
typedef vector<AnalyzerElement*> AnalyzerElementList;
|
||||
typedef vector<Attr*> AttrList;
|
||||
typedef vector<CaseExpr*> CaseExprList;
|
||||
typedef vector<CaseField*> CaseFieldList;
|
||||
typedef vector<ContextField*> ContextFieldList;
|
||||
typedef vector<Decl*> DeclList;
|
||||
typedef vector<Enum*> EnumList;
|
||||
typedef vector<Expr*> ExprList;
|
||||
typedef vector<Field*> FieldList;
|
||||
typedef vector<LetField*> LetFieldList;
|
||||
typedef vector<Number*> NumList;
|
||||
typedef vector<Param*> ParamList;
|
||||
typedef vector<RecordField*> RecordFieldList;
|
||||
typedef vector<StateVar*> StateVarList;
|
||||
|
||||
#define foreach(i, ct, pc) \
|
||||
if ( pc ) \
|
||||
for ( ct::iterator i = (pc)->begin(); i != (pc)->end(); ++i )
|
||||
|
||||
#define delete_list(ct, pc) \
|
||||
{ \
|
||||
foreach(delete_list_i, ct, pc) \
|
||||
delete *delete_list_i; \
|
||||
delete pc; \
|
||||
pc = 0; \
|
||||
}
|
||||
|
||||
// Constants
|
||||
const char * const kComputeFrameLength = "compute_frame_length";
|
||||
const char * const kFlowBufferClass = "FlowBuffer";
|
||||
const char * const kFlowBufferVar = "flow_buffer";
|
||||
const char * const kFlowEOF = "FlowEOF";
|
||||
const char * const kFlowGap = "NewGap";
|
||||
const char * const kInitialBufferLengthFunc = "initial_buffer_length";
|
||||
const char * const kNeedMoreData = "need_more_data";
|
||||
const char * const kNewData = "NewData";
|
||||
const char * const kParseFuncWithBuffer = "ParseBuffer";
|
||||
const char * const kParseFuncWithoutBuffer = "Parse";
|
||||
const char * const kRefCountClass = "binpac::RefCount";
|
||||
const char * const kTypeWithLengthClass = "binpac::TypeWithLength";
|
||||
|
||||
#endif // pac_common_h
|
|
@ -1,169 +0,0 @@
|
|||
#include "pac_analyzer.h"
|
||||
#include "pac_dataunit.h"
|
||||
#include "pac_embedded.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_flow.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_paramtype.h"
|
||||
#include "pac_type.h"
|
||||
|
||||
#include "pac_conn.h"
|
||||
|
||||
ConnDecl::ConnDecl(ID *conn_id,
|
||||
ParamList *params,
|
||||
AnalyzerElementList *elemlist)
|
||||
: AnalyzerDecl(conn_id, CONN, params)
|
||||
{
|
||||
flows_[0] = flows_[1] = 0;
|
||||
AddElements(elemlist);
|
||||
data_type_ = new ParameterizedType(conn_id->clone(), 0);
|
||||
}
|
||||
|
||||
ConnDecl::~ConnDecl()
|
||||
{
|
||||
delete flows_[0];
|
||||
delete flows_[1];
|
||||
}
|
||||
|
||||
void ConnDecl::AddBaseClass(vector<string> *base_classes) const
|
||||
{
|
||||
base_classes->push_back("binpac::ConnectionAnalyzer");
|
||||
}
|
||||
|
||||
void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem)
|
||||
{
|
||||
int flow_index;
|
||||
|
||||
if ( flow_elem->dir() == AnalyzerFlow::UP )
|
||||
flow_index = 0;
|
||||
else
|
||||
flow_index = 1;
|
||||
|
||||
if ( flows_[flow_index] )
|
||||
{
|
||||
throw Exception(flow_elem,
|
||||
fmt("%sflow already defined",
|
||||
flow_index == 0 ? "up" : "down"));
|
||||
}
|
||||
|
||||
flows_[flow_index] = flow_elem;
|
||||
type_->AddField(flow_elem->flow_field());
|
||||
}
|
||||
|
||||
void ConnDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem)
|
||||
{
|
||||
throw Exception(
|
||||
dataunit_elem,
|
||||
"dataunit should be defined in only a flow declaration");
|
||||
}
|
||||
|
||||
void ConnDecl::Prepare()
|
||||
{
|
||||
AnalyzerDecl::Prepare();
|
||||
|
||||
flows_[0]->flow_decl()->set_conn_decl(this);
|
||||
flows_[1]->flow_decl()->set_conn_decl(this);
|
||||
}
|
||||
|
||||
void ConnDecl::GenPubDecls(Output *out_h, Output *out_cc)
|
||||
{
|
||||
AnalyzerDecl::GenPubDecls(out_h, out_cc);
|
||||
}
|
||||
|
||||
void ConnDecl::GenPrivDecls(Output *out_h, Output *out_cc)
|
||||
{
|
||||
AnalyzerDecl::GenPrivDecls(out_h, out_cc);
|
||||
}
|
||||
|
||||
void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc)
|
||||
{
|
||||
string proto = strfmt("%s(bool is_orig)", kFlowEOF);
|
||||
|
||||
out_h->println("void %s;", proto.c_str());
|
||||
|
||||
out_cc->println("void %s::%s", class_name().c_str(), proto.c_str());
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
out_cc->println("if ( is_orig )");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("%s->%s();",
|
||||
env_->LValue(upflow_id),
|
||||
kFlowEOF);
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("else");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("%s->%s();",
|
||||
env_->LValue(downflow_id),
|
||||
kFlowEOF);
|
||||
|
||||
foreach(i, AnalyzerHelperList, eof_helpers_)
|
||||
{
|
||||
(*i)->GenCode(0, out_cc, this);
|
||||
}
|
||||
|
||||
out_cc->dec_indent();
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("");
|
||||
}
|
||||
|
||||
void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc)
|
||||
{
|
||||
string proto = strfmt("%s(bool is_orig, int gap_length)", kFlowGap);
|
||||
|
||||
out_h->println("void %s;", proto.c_str());
|
||||
|
||||
out_cc->println("void %s::%s", class_name().c_str(), proto.c_str());
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
out_cc->println("if ( is_orig )");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("%s->%s(gap_length);",
|
||||
env_->LValue(upflow_id),
|
||||
kFlowGap);
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("else");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("%s->%s(gap_length);",
|
||||
env_->LValue(downflow_id),
|
||||
kFlowGap);
|
||||
out_cc->dec_indent();
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("");
|
||||
}
|
||||
|
||||
void ConnDecl::GenProcessFunc(Output *out_h, Output *out_cc)
|
||||
{
|
||||
string proto =
|
||||
strfmt("%s(bool is_orig, const_byteptr begin, const_byteptr end)",
|
||||
kNewData);
|
||||
|
||||
out_h->println("void %s;", proto.c_str());
|
||||
|
||||
out_cc->println("void %s::%s", class_name().c_str(), proto.c_str());
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
out_cc->println("if ( is_orig )");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("%s->%s(begin, end);",
|
||||
env_->LValue(upflow_id),
|
||||
kNewData);
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("else");
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("%s->%s(begin, end);",
|
||||
env_->LValue(downflow_id),
|
||||
kNewData);
|
||||
out_cc->dec_indent();
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
out_cc->println("");
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef pac_conn_h
|
||||
#define pac_conn_h
|
||||
|
||||
#include "pac_decl.h"
|
||||
#include "pac_analyzer.h"
|
||||
|
||||
class ConnDecl : public AnalyzerDecl
|
||||
{
|
||||
public:
|
||||
ConnDecl(ID *conn_id, ParamList *params, AnalyzerElementList *elemlist);
|
||||
~ConnDecl();
|
||||
|
||||
void Prepare();
|
||||
|
||||
Type* DataType() const { return data_type_; }
|
||||
|
||||
protected:
|
||||
void AddBaseClass(vector<string> *base_classes) const;
|
||||
|
||||
void GenProcessFunc(Output *out_h, Output *out_cc);
|
||||
void GenGapFunc(Output *out_h, Output *out_cc);
|
||||
void GenEOFFunc(Output *out_h, Output *out_cc);
|
||||
|
||||
void GenPubDecls(Output *out_h, Output *out_cc);
|
||||
void GenPrivDecls(Output *out_h, Output *out_cc);
|
||||
|
||||
void ProcessFlowElement(AnalyzerFlow *flow_elem);
|
||||
void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem);
|
||||
|
||||
AnalyzerFlow *flows_[2];
|
||||
Type *data_type_;
|
||||
};
|
||||
|
||||
#endif // pac_conn_h
|
|
@ -1,120 +0,0 @@
|
|||
#include "pac_analyzer.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_exttype.h"
|
||||
#include "pac_flow.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_param.h"
|
||||
#include "pac_paramtype.h"
|
||||
#include "pac_type.h"
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include "pac_context.h"
|
||||
|
||||
ContextField::ContextField(ID *id, Type *type)
|
||||
: Field(CONTEXT_FIELD,
|
||||
TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE,
|
||||
id, type)
|
||||
{
|
||||
}
|
||||
|
||||
AnalyzerContextDecl *AnalyzerContextDecl::current_analyzer_context_ = 0;
|
||||
|
||||
namespace {
|
||||
ParamList *ContextFieldsToParams(ContextFieldList *context_fields)
|
||||
{
|
||||
// Convert context fields to parameters
|
||||
ParamList *params = new ParamList();
|
||||
foreach(i, ContextFieldList, context_fields)
|
||||
{
|
||||
ContextField *f = *i;
|
||||
params->push_back(
|
||||
new Param(f->id()->clone(),
|
||||
f->type()));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
} // namespace private
|
||||
|
||||
AnalyzerContextDecl::AnalyzerContextDecl(
|
||||
ID *id,
|
||||
ContextFieldList *context_fields)
|
||||
: TypeDecl(new ID(fmt("Context%s", id->Name())),
|
||||
ContextFieldsToParams(context_fields),
|
||||
new DummyType())
|
||||
{
|
||||
context_name_id_ = id;
|
||||
if ( current_analyzer_context_ != 0 )
|
||||
{
|
||||
throw Exception(this,
|
||||
fmt("multiple declaration of analyzer context; "
|
||||
"the previous one is `%s'",
|
||||
current_analyzer_context_->id()->Name()));
|
||||
}
|
||||
else
|
||||
current_analyzer_context_ = this;
|
||||
|
||||
context_fields_ = context_fields;
|
||||
|
||||
param_type_ = new ParameterizedType(id_->clone(), 0);
|
||||
|
||||
flow_buffer_added_ = false;
|
||||
|
||||
DEBUG_MSG("Context type: %s\n", param_type()->class_name().c_str());
|
||||
}
|
||||
|
||||
AnalyzerContextDecl::~AnalyzerContextDecl()
|
||||
{
|
||||
delete context_name_id_;
|
||||
delete_list(ContextFieldList, context_fields_);
|
||||
}
|
||||
|
||||
void AnalyzerContextDecl::GenForwardDeclaration(Output *out_h)
|
||||
{
|
||||
GenNamespaceBegin(out_h);
|
||||
TypeDecl::GenForwardDeclaration(out_h);
|
||||
}
|
||||
|
||||
void AnalyzerContextDecl::GenCode(Output *out_h, Output *out_cc)
|
||||
{
|
||||
GenNamespaceBegin(out_h);
|
||||
GenNamespaceBegin(out_cc);
|
||||
TypeDecl::GenCode(out_h, out_cc);
|
||||
}
|
||||
|
||||
void AnalyzerContextDecl::GenNamespaceBegin(Output *out) const
|
||||
{
|
||||
out->println("namespace %s {", context_name_id()->Name());
|
||||
}
|
||||
|
||||
void AnalyzerContextDecl::GenNamespaceEnd(Output *out) const
|
||||
{
|
||||
out->println("} // namespace %s", context_name_id()->Name());
|
||||
}
|
||||
|
||||
void AnalyzerContextDecl::AddFlowBuffer()
|
||||
{
|
||||
if ( flow_buffer_added_ )
|
||||
return;
|
||||
|
||||
AddParam(new Param(
|
||||
new ID(kFlowBufferVar),
|
||||
FlowDecl::flow_buffer_type()->Clone()));
|
||||
|
||||
flow_buffer_added_ = true;
|
||||
}
|
||||
|
||||
string AnalyzerContextDecl::mb_buffer(Env *env)
|
||||
{
|
||||
// A hack. The orthodox way would be to build an Expr of
|
||||
// context.flow_buffer_var, and then EvalExpr.
|
||||
return fmt("%s->%s()",
|
||||
env->RValue(analyzer_context_id),
|
||||
kFlowBufferVar);
|
||||
}
|
||||
|
||||
Type *DummyType::DoClone() const
|
||||
{
|
||||
// Fields will be copied in Type::Clone().
|
||||
return new DummyType();
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
#ifndef pac_context_h
|
||||
#define pac_context_h
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_field.h"
|
||||
#include "pac_type.h"
|
||||
#include "pac_typedecl.h"
|
||||
|
||||
// AnalyzerContext represents a cookie that an analyzer gives to
|
||||
// parse functions of various message types. The cookie is parsed
|
||||
// to every parse function (if necessary) as parameter 'binpac_context'.
|
||||
//
|
||||
// The members of the cookie is declared through 'analyzer' declarations,
|
||||
// such as in:
|
||||
//
|
||||
// analyzer SunRPC withcontext {
|
||||
// connection: RPC_Conn;
|
||||
// flow: RPC_Flow;
|
||||
// };
|
||||
//
|
||||
// The cookie usually contains the connection and flow in which
|
||||
// the message appears, and the context information can be
|
||||
// accessed as members of the cookie, such as
|
||||
// ``binpac_context.connection''.
|
||||
|
||||
class ContextField : public Field
|
||||
{
|
||||
public:
|
||||
ContextField(ID *id, Type *type);
|
||||
};
|
||||
|
||||
class AnalyzerContextDecl : public TypeDecl
|
||||
{
|
||||
public:
|
||||
AnalyzerContextDecl(ID *id, ContextFieldList *context_fields);
|
||||
~AnalyzerContextDecl();
|
||||
|
||||
void AddFlowBuffer();
|
||||
|
||||
const ID *context_name_id() const { return context_name_id_; }
|
||||
|
||||
// The type of analyzer context as a parameter
|
||||
ParameterizedType *param_type() const { return param_type_; }
|
||||
|
||||
void GenForwardDeclaration(Output *out_h);
|
||||
void GenCode(Output *out_h, Output *out_cc);
|
||||
|
||||
void GenNamespaceBegin(Output *out) const;
|
||||
void GenNamespaceEnd(Output *out) const;
|
||||
|
||||
private:
|
||||
ID *context_name_id_;
|
||||
ContextFieldList *context_fields_;
|
||||
ParameterizedType *param_type_;
|
||||
bool flow_buffer_added_;
|
||||
|
||||
// static members
|
||||
public:
|
||||
static AnalyzerContextDecl *current_analyzer_context()
|
||||
{
|
||||
return current_analyzer_context_;
|
||||
}
|
||||
|
||||
static string mb_buffer(Env *env);
|
||||
|
||||
private:
|
||||
static AnalyzerContextDecl *current_analyzer_context_;
|
||||
};
|
||||
|
||||
class DummyType : public Type
|
||||
{
|
||||
public:
|
||||
DummyType() : Type(DUMMY) {}
|
||||
|
||||
bool DefineValueVar() const { return false; }
|
||||
string DataTypeStr() const { ASSERT(0); return ""; }
|
||||
|
||||
int StaticSize(Env* env) const { ASSERT(0); return -1; }
|
||||
|
||||
bool ByteOrderSensitive() const { return false; }
|
||||
|
||||
bool IsPointerType() const { ASSERT(0); return false; }
|
||||
|
||||
void DoGenParseCode(Output* out, Env* env,
|
||||
const DataPtr& data, int flags)
|
||||
{ ASSERT(0); }
|
||||
|
||||
// Generate code for computing the dynamic size of the type
|
||||
void GenDynamicSize(Output* out, Env* env, const DataPtr& data)
|
||||
{ ASSERT(0); }
|
||||
|
||||
protected:
|
||||
Type *DoClone() const;
|
||||
void DoMarkIncrementalInput() { ASSERT(0); }
|
||||
};
|
||||
|
||||
#endif // pac_context_h
|
|
@ -1,127 +0,0 @@
|
|||
#include "pac_cstr.h"
|
||||
#include "pac_dbg.h"
|
||||
#include "pac_exception.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class EscapeException
|
||||
{
|
||||
public:
|
||||
explicit EscapeException(const string &s)
|
||||
{
|
||||
msg_ = s;
|
||||
}
|
||||
|
||||
const string &msg() const { return msg_; }
|
||||
|
||||
private:
|
||||
string msg_;
|
||||
};
|
||||
|
||||
// Copied from util.cc of Bro
|
||||
int expand_escape(const char*& s)
|
||||
{
|
||||
switch ( *(s++) ) {
|
||||
case 'b': return '\b';
|
||||
case 'f': return '\f';
|
||||
case 'n': return '\n';
|
||||
case 'r': return '\r';
|
||||
case 't': return '\t';
|
||||
case 'a': return '\a';
|
||||
case 'v': return '\v';
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7':
|
||||
{ // \<octal>{1,3}
|
||||
--s; // put back the first octal digit
|
||||
const char* start = s;
|
||||
|
||||
// Don't increment inside loop control
|
||||
// because if isdigit() is a macro it might
|
||||
// expand into multiple increments ...
|
||||
|
||||
// Here we define a maximum length for escape sequence
|
||||
// to allow easy handling of string like: "^H0" as
|
||||
// "\0100".
|
||||
|
||||
for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s); ++s, ++len)
|
||||
;
|
||||
|
||||
int result;
|
||||
if ( sscanf(start, "%3o", &result) != 1 )
|
||||
{
|
||||
throw EscapeException(fmt("bad octal escape: \"%s", start));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
case 'x':
|
||||
{ /* \x<hex> */
|
||||
const char* start = s;
|
||||
|
||||
// Look at most 2 characters, so that "\x0ddir" -> "^Mdir".
|
||||
for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s);
|
||||
++s, ++len)
|
||||
;
|
||||
|
||||
int result;
|
||||
if ( sscanf(start, "%2x", &result) != 1 )
|
||||
{
|
||||
throw EscapeException(fmt("bad hexadecimal escape: \"%s", start));
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
default:
|
||||
return s[-1];
|
||||
}
|
||||
}
|
||||
|
||||
} // private namespace
|
||||
|
||||
ConstString::ConstString(const string &s)
|
||||
: str_(s)
|
||||
{
|
||||
// Copied from scan.l of Bro
|
||||
try
|
||||
{
|
||||
const char* text = str_.c_str();
|
||||
int len = strlen(text) + 1;
|
||||
int i = 0;
|
||||
|
||||
char* s = new char[len];
|
||||
|
||||
// Skip leading quote.
|
||||
for ( ++text; *text; ++text )
|
||||
{
|
||||
if ( *text == '\\' )
|
||||
{
|
||||
++text; // skip '\'
|
||||
s[i++] = expand_escape(text);
|
||||
--text; // point to end of sequence
|
||||
}
|
||||
else
|
||||
{
|
||||
s[i++] = *text;
|
||||
}
|
||||
}
|
||||
ASSERT(i < len);
|
||||
|
||||
// Get rid of trailing quote.
|
||||
ASSERT(s[i-1] == '"');
|
||||
s[i-1] = '\0';
|
||||
|
||||
unescaped_ = s;
|
||||
delete [] s;
|
||||
}
|
||||
catch(EscapeException const &e)
|
||||
{
|
||||
// Throw again with the object
|
||||
throw Exception(this, e.msg().c_str());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef pac_cstr_h
|
||||
#define pac_cstr_h
|
||||
|
||||
#include "pac_common.h"
|
||||
|
||||
class ConstString : public Object
|
||||
{
|
||||
public:
|
||||
ConstString(const string &s);
|
||||
|
||||
// The string in its escaped form, with surrounding '"'s
|
||||
const string &str() const { return str_; }
|
||||
const char *c_str() const { return str_.c_str(); }
|
||||
|
||||
// The unescaped string, without surrounding '"'s
|
||||
const string &unescaped() const { return unescaped_; }
|
||||
|
||||
private:
|
||||
string str_;
|
||||
string unescaped_;
|
||||
};
|
||||
|
||||
#endif // pac_cstr_h
|
|
@ -1,21 +0,0 @@
|
|||
#include "pac_ctype.h"
|
||||
|
||||
string CType::DeclareInstance(const string &var) const
|
||||
{
|
||||
return strfmt("%s %s", name().c_str(), var.c_str());
|
||||
}
|
||||
|
||||
string CType::DeclareConstReference(const string &var) const
|
||||
{
|
||||
return strfmt("%s const &%s", name().c_str(), var.c_str());
|
||||
}
|
||||
|
||||
string CType::DeclareConstPointer(const string &var) const
|
||||
{
|
||||
return strfmt("%s const *%s", name().c_str(), var.c_str());
|
||||
}
|
||||
|
||||
string CType::DeclarePointer(const string &var) const
|
||||
{
|
||||
return strfmt("%s *%s", name().c_str(), var.c_str());
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef pac_ctype_h
|
||||
#define pac_ctype_h
|
||||
|
||||
#include "pac_common.h"
|
||||
|
||||
// Represents a C++ type
|
||||
class CType
|
||||
{
|
||||
public:
|
||||
CType(const string &name);
|
||||
|
||||
string name() const { return name_; }
|
||||
|
||||
string DeclareInstance(const string &var) const;
|
||||
string DeclareConstReference(const string &var) const;
|
||||
string DeclareConstPointer(const string &var) const;
|
||||
string DeclarePointer(const string &var) const;
|
||||
|
||||
protected:
|
||||
string name_;
|
||||
};
|
||||
|
||||
#endif // pac_ctype_h
|
|
@ -1,76 +0,0 @@
|
|||
#include "pac_datadep.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_type.h"
|
||||
|
||||
DataDepElement::DataDepElement(DDE_Type type)
|
||||
: dde_type_(type), in_traversal(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool DataDepElement::Traverse(DataDepVisitor *visitor)
|
||||
{
|
||||
// Avoid infinite loop
|
||||
if ( in_traversal )
|
||||
return true;
|
||||
if ( ! visitor->PreProcess(this) )
|
||||
return false;
|
||||
|
||||
in_traversal = true;
|
||||
bool cont = DoTraverse(visitor);
|
||||
in_traversal = false;
|
||||
|
||||
if ( ! cont )
|
||||
return false;
|
||||
if ( ! visitor->PostProcess(this) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Expr *DataDepElement::expr()
|
||||
{
|
||||
return static_cast<Expr *>(this);
|
||||
}
|
||||
|
||||
Type *DataDepElement::type()
|
||||
{
|
||||
return static_cast<Type *>(this);
|
||||
}
|
||||
|
||||
bool RequiresAnalyzerContext::PreProcess(DataDepElement *element)
|
||||
{
|
||||
switch ( element->dde_type() )
|
||||
{
|
||||
case DataDepElement::EXPR:
|
||||
ProcessExpr(element->expr());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Continue traversal until we know the answer is 'yes'
|
||||
return ! requires_analyzer_context_;
|
||||
}
|
||||
|
||||
bool RequiresAnalyzerContext::PostProcess(DataDepElement *element)
|
||||
{
|
||||
return ! requires_analyzer_context_;
|
||||
}
|
||||
|
||||
void RequiresAnalyzerContext::ProcessExpr(Expr *expr)
|
||||
{
|
||||
if ( expr->expr_type() == Expr::EXPR_ID )
|
||||
{
|
||||
requires_analyzer_context_ =
|
||||
(requires_analyzer_context_ ||
|
||||
*expr->id() == *analyzer_context_id ||
|
||||
*expr->id() == *context_macro_id);
|
||||
}
|
||||
}
|
||||
|
||||
bool RequiresAnalyzerContext::compute(DataDepElement *element)
|
||||
{
|
||||
RequiresAnalyzerContext visitor;
|
||||
element->Traverse(&visitor);
|
||||
return visitor.requires_analyzer_context_;
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
#ifndef pac_datadep_h
|
||||
#define pac_datadep_h
|
||||
|
||||
// To provide a way to traverse through the data dependency graph.
|
||||
// That is, to evaluate X, what must be evaluated.
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_dbg.h"
|
||||
|
||||
class DataDepVisitor;
|
||||
|
||||
class DataDepElement {
|
||||
public:
|
||||
enum DDE_Type {
|
||||
ATTR,
|
||||
CASEEXPR,
|
||||
EXPR,
|
||||
FIELD,
|
||||
INPUT_BUFFER,
|
||||
PARAM,
|
||||
TYPE,
|
||||
};
|
||||
|
||||
DataDepElement(DDE_Type type);
|
||||
virtual ~DataDepElement() {}
|
||||
|
||||
// Returns whether to continue traversal
|
||||
bool Traverse(DataDepVisitor *visitor);
|
||||
|
||||
// Returns whether to continue traversal
|
||||
virtual bool DoTraverse(DataDepVisitor *visitor) = 0;
|
||||
|
||||
DDE_Type dde_type() const { return dde_type_; }
|
||||
Expr *expr();
|
||||
Type *type();
|
||||
|
||||
protected:
|
||||
DDE_Type dde_type_;
|
||||
bool in_traversal;
|
||||
};
|
||||
|
||||
class DataDepVisitor {
|
||||
public:
|
||||
virtual ~DataDepVisitor() {}
|
||||
// Returns whether to continue traversal
|
||||
virtual bool PreProcess(DataDepElement *element) = 0;
|
||||
virtual bool PostProcess(DataDepElement *element) = 0;
|
||||
};
|
||||
|
||||
class RequiresAnalyzerContext : public DataDepVisitor {
|
||||
public:
|
||||
RequiresAnalyzerContext() : requires_analyzer_context_(false) {}
|
||||
|
||||
// Returns whether to continue traversal
|
||||
bool PreProcess(DataDepElement *element);
|
||||
bool PostProcess(DataDepElement *element);
|
||||
|
||||
bool requires_analyzer_context() const
|
||||
{
|
||||
return requires_analyzer_context_;
|
||||
}
|
||||
|
||||
static bool compute(DataDepElement *element);
|
||||
|
||||
protected:
|
||||
void ProcessExpr(Expr *expr);
|
||||
|
||||
bool requires_analyzer_context_;
|
||||
};
|
||||
|
||||
#endif // pac_datadep_h
|
|
@ -1,66 +0,0 @@
|
|||
#include "pac_exception.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include "pac_dataptr.h"
|
||||
|
||||
DataPtr::DataPtr(Env* env, const ID* id, const int offset)
|
||||
: id_(id), offset_(offset)
|
||||
{
|
||||
if ( id_ )
|
||||
{
|
||||
if ( ! env->Evaluated(id_) )
|
||||
throw ExceptionIDNotEvaluated(id_);
|
||||
|
||||
if ( offset_ == 0 )
|
||||
ptr_expr_ = strfmt("%s", env->RValue(id_));
|
||||
else
|
||||
ptr_expr_ = strfmt("(%s + %d)", env->RValue(id_), offset_);
|
||||
}
|
||||
else
|
||||
ptr_expr_ = "(null id)";
|
||||
}
|
||||
|
||||
int DataPtr::AbsOffset(const ID* base_ptr) const
|
||||
{
|
||||
return ( id() == base_ptr ) ? offset() : -1;
|
||||
}
|
||||
|
||||
char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const
|
||||
{
|
||||
if ( AbsOffset(base_ptr) >= 0 )
|
||||
return nfmt("%d", offset());
|
||||
else
|
||||
return nfmt("(%s - %s)", ptr_expr(), env->RValue(base_ptr));
|
||||
}
|
||||
|
||||
void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env,
|
||||
const char* data_size, const char* data_name) const
|
||||
{
|
||||
ASSERT(id_);
|
||||
|
||||
out_cc->println("// Checking out-of-bound for \"%s\"", data_name);
|
||||
out_cc->println("if ( %s + (%s) > %s )",
|
||||
ptr_expr(),
|
||||
data_size,
|
||||
env->RValue(end_of_data));
|
||||
|
||||
out_cc->inc_indent();
|
||||
out_cc->println("{");
|
||||
|
||||
char* data_offset = AbsOffsetExpr(env, begin_of_data);
|
||||
|
||||
out_cc->println("// Handle out-of-bound condition");
|
||||
out_cc->println("throw ExceptionOutOfBound(\"%s\",", data_name);
|
||||
out_cc->println(" (%s) + (%s), ",
|
||||
data_offset, data_size);
|
||||
out_cc->println(" (%s) - (%s));",
|
||||
env->RValue(end_of_data), env->RValue(begin_of_data));
|
||||
|
||||
delete [] data_offset;
|
||||
|
||||
out_cc->println("}");
|
||||
out_cc->dec_indent();
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#ifndef pac_dataptr_h
|
||||
#define pac_dataptr_h
|
||||
|
||||
#include <string>
|
||||
#include "pac_common.h"
|
||||
|
||||
// A data pointer is represented by an data pointer variable
|
||||
// plus a constant offset.
|
||||
|
||||
class DataPtr
|
||||
{
|
||||
public:
|
||||
DataPtr(Env* env, const ID* arg_id, const int arg_off);
|
||||
|
||||
DataPtr const &operator=(DataPtr const &x)
|
||||
{
|
||||
id_ = x.id();
|
||||
offset_ = x.offset();
|
||||
ptr_expr_ = x.ptr_expr();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const ID* id() const { return id_; }
|
||||
int offset() const { return offset_; }
|
||||
|
||||
const char* ptr_expr() const
|
||||
{
|
||||
ASSERT(id_);
|
||||
return ptr_expr_.c_str();
|
||||
}
|
||||
|
||||
int AbsOffset(const ID* base_ptr) const;
|
||||
char* AbsOffsetExpr(Env* env, const ID* base_ptr) const;
|
||||
|
||||
void GenBoundaryCheck(Output* out,
|
||||
Env* env,
|
||||
const char* data_size,
|
||||
const char* data_name) const;
|
||||
|
||||
protected:
|
||||
const ID* id_;
|
||||
int offset_;
|
||||
string ptr_expr_;
|
||||
};
|
||||
|
||||
#endif // pac_dataptr_h
|
|
@ -1,60 +0,0 @@
|
|||
#include "pac_context.h"
|
||||
#include "pac_dataunit.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_paramtype.h"
|
||||
#include "pac_varfield.h"
|
||||
|
||||
AnalyzerDataUnit::AnalyzerDataUnit(
|
||||
DataUnitType type,
|
||||
ID *id,
|
||||
ExprList *type_params,
|
||||
ExprList *context_params)
|
||||
: AnalyzerElement(DATAUNIT),
|
||||
type_(type),
|
||||
id_(id),
|
||||
type_params_(type_params),
|
||||
context_params_(context_params)
|
||||
{
|
||||
data_type_ = new ParameterizedType(id_, type_params_);
|
||||
context_type_ = new ParameterizedType(
|
||||
AnalyzerContextDecl::current_analyzer_context()->id()->clone(),
|
||||
context_params_);
|
||||
|
||||
dataunit_var_field_ = new ParseVarField(
|
||||
Field::CLASS_MEMBER,
|
||||
dataunit_id->clone(),
|
||||
data_type());
|
||||
context_var_field_ = new PrivVarField(
|
||||
analyzer_context_id->clone(),
|
||||
context_type());
|
||||
}
|
||||
|
||||
AnalyzerDataUnit::~AnalyzerDataUnit()
|
||||
{
|
||||
delete dataunit_var_field_;
|
||||
delete context_var_field_;
|
||||
}
|
||||
|
||||
void AnalyzerDataUnit::Prepare(Env *env)
|
||||
{
|
||||
dataunit_var_field_->Prepare(env);
|
||||
context_var_field_->Prepare(env);
|
||||
}
|
||||
|
||||
void AnalyzerDataUnit::GenNewDataUnit(Output *out_cc, Env *env)
|
||||
{
|
||||
out_cc->println("%s = new %s(%s);",
|
||||
env->LValue(dataunit_id),
|
||||
data_type()->class_name().c_str(),
|
||||
data_type()->EvalParameters(out_cc, env).c_str());
|
||||
}
|
||||
|
||||
void AnalyzerDataUnit::GenNewContext(Output *out_cc, Env *env)
|
||||
{
|
||||
out_cc->println("%s = new %s(%s);",
|
||||
env->LValue(analyzer_context_id),
|
||||
context_type()->class_name().c_str(),
|
||||
context_type()->EvalParameters(out_cc, env).c_str());
|
||||
env->SetEvaluated(analyzer_context_id);
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
#ifndef pac_dataunit_h
|
||||
#define pac_dataunit_h
|
||||
|
||||
#include "pac_analyzer.h"
|
||||
|
||||
// The type and parameters of input data unit of a flow. For instance, the
|
||||
// data unit of a DCE/RPC flow is DCE_RPC_PDU.
|
||||
|
||||
class AnalyzerDataUnit : public AnalyzerElement
|
||||
{
|
||||
public:
|
||||
enum DataUnitType { DATAGRAM, FLOWUNIT };
|
||||
AnalyzerDataUnit(
|
||||
DataUnitType type,
|
||||
ID *id,
|
||||
ExprList *type_params,
|
||||
ExprList *context_params);
|
||||
~AnalyzerDataUnit();
|
||||
|
||||
void Prepare(Env *env);
|
||||
|
||||
// Initializes dataunit_id
|
||||
void GenNewDataUnit(Output *out_cc, Env *env);
|
||||
// Initializes analyzer_context_id
|
||||
void GenNewContext(Output *out_cc, Env *env);
|
||||
|
||||
DataUnitType type() const { return type_; }
|
||||
const ID *id() const { return id_; }
|
||||
ExprList *type_params() const { return type_params_; }
|
||||
ExprList *context_params() const { return context_params_; }
|
||||
|
||||
ParameterizedType *data_type() const { return data_type_; }
|
||||
ParameterizedType *context_type() const { return context_type_; }
|
||||
|
||||
Field *dataunit_var_field() const { return dataunit_var_field_; }
|
||||
Field *context_var_field() const { return context_var_field_; }
|
||||
|
||||
private:
|
||||
DataUnitType type_;
|
||||
ID *id_;
|
||||
ExprList *type_params_;
|
||||
ExprList *context_params_;
|
||||
ParameterizedType *data_type_;
|
||||
ParameterizedType *context_type_;
|
||||
Field *dataunit_var_field_;
|
||||
Field *context_var_field_;
|
||||
};
|
||||
|
||||
#endif // pac_dataunit_h
|
|
@ -1,14 +0,0 @@
|
|||
/* $Id: pac_dbg.h 3265 2006-06-09 21:16:12Z rpang $ */
|
||||
|
||||
#ifndef pac_dbg_h
|
||||
#define pac_dbg_h
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern bool FLAGS_pac_debug;
|
||||
|
||||
#define ASSERT(x) assert(x)
|
||||
#define DEBUG_MSG(x...) if ( FLAGS_pac_debug ) fprintf(stderr, x)
|
||||
|
||||
#endif /* pac_dbg_h */
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef pac_decl_inl_h
|
||||
#define pac_decl_inl_h
|
||||
|
||||
#include "pac_id.h"
|
||||
|
||||
#endif // pac_decl_inl_h
|
|
@ -1,191 +0,0 @@
|
|||
#include "pac_attr.h"
|
||||
#include "pac_context.h"
|
||||
#include "pac_dataptr.h"
|
||||
#include "pac_embedded.h"
|
||||
#include "pac_exception.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_exttype.h"
|
||||
#include "pac_id.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_param.h"
|
||||
#include "pac_record.h"
|
||||
#include "pac_type.h"
|
||||
#include "pac_utils.h"
|
||||
|
||||
#include "pac_decl.h"
|
||||
|
||||
DeclList *Decl::decl_list_ = 0;
|
||||
Decl::DeclMap Decl::decl_map_;
|
||||
|
||||
Decl::Decl(ID* id, DeclType decl_type)
|
||||
: id_(id), decl_type_(decl_type), attrlist_(0)
|
||||
{
|
||||
decl_map_[id_] = this;
|
||||
if ( ! decl_list_ )
|
||||
decl_list_ = new DeclList();
|
||||
decl_list_->push_back(this);
|
||||
|
||||
DEBUG_MSG("Finished Decl %s\n", id_->Name());
|
||||
|
||||
analyzer_context_ = 0;
|
||||
}
|
||||
|
||||
Decl::~Decl()
|
||||
{
|
||||
delete id_;
|
||||
delete_list(AttrList, attrlist_);
|
||||
}
|
||||
|
||||
void Decl::AddAttrs(AttrList* attrs)
|
||||
{
|
||||
if ( ! attrs )
|
||||
return;
|
||||
if ( ! attrlist_ )
|
||||
attrlist_ = new AttrList();
|
||||
foreach ( i, AttrList, attrs )
|
||||
{
|
||||
attrlist_->push_back(*i);
|
||||
ProcessAttr(*i);
|
||||
}
|
||||
}
|
||||
|
||||
void Decl::ProcessAttr(Attr *attr)
|
||||
{
|
||||
throw Exception(attr, "unhandled attribute");
|
||||
}
|
||||
|
||||
void Decl::SetAnalyzerContext()
|
||||
{
|
||||
analyzer_context_ =
|
||||
AnalyzerContextDecl::current_analyzer_context();
|
||||
if ( ! analyzer_context_ )
|
||||
{
|
||||
throw Exception(this,
|
||||
"analyzer context not defined");
|
||||
}
|
||||
}
|
||||
|
||||
void Decl::ProcessDecls(Output *out_h, Output *out_cc)
|
||||
{
|
||||
if ( ! decl_list_ )
|
||||
return;
|
||||
|
||||
foreach(i, DeclList, decl_list_)
|
||||
{
|
||||
Decl *decl = *i;
|
||||
current_decl_id = decl->id();
|
||||
decl->Prepare();
|
||||
}
|
||||
|
||||
foreach(i, DeclList, decl_list_)
|
||||
{
|
||||
Decl *decl = *i;
|
||||
current_decl_id = decl->id();
|
||||
decl->GenExternDeclaration(out_h);
|
||||
}
|
||||
|
||||
out_h->println("namespace binpac {\n");
|
||||
out_cc->println("namespace binpac {\n");
|
||||
|
||||
AnalyzerContextDecl *analyzer_context =
|
||||
AnalyzerContextDecl::current_analyzer_context();
|
||||
|
||||
foreach(i, DeclList, decl_list_)
|
||||
{
|
||||
Decl *decl = *i;
|
||||
current_decl_id = decl->id();
|
||||
decl->GenForwardDeclaration(out_h);
|
||||
}
|
||||
|
||||
if ( analyzer_context )
|
||||
analyzer_context->GenNamespaceEnd(out_h);
|
||||
|
||||
out_h->println("");
|
||||
|
||||
foreach(i, DeclList, decl_list_)
|
||||
{
|
||||
Decl *decl = *i;
|
||||
current_decl_id = decl->id();
|
||||
decl->GenCode(out_h, out_cc);
|
||||
}
|
||||
|
||||
if ( analyzer_context )
|
||||
{
|
||||
analyzer_context->GenNamespaceEnd(out_h);
|
||||
analyzer_context->GenNamespaceEnd(out_cc);
|
||||
}
|
||||
|
||||
out_h->println("} // namespace binpac");
|
||||
out_cc->println("} // namespace binpac");
|
||||
}
|
||||
|
||||
Decl* Decl::LookUpDecl(const ID* id)
|
||||
{
|
||||
DeclMap::iterator it = decl_map_.find(id);
|
||||
if ( it == decl_map_.end() )
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int HelperDecl::helper_id_seq = 0;
|
||||
|
||||
HelperDecl::HelperDecl(HelperType helper_type,
|
||||
ID* context_id,
|
||||
EmbeddedCode* code)
|
||||
: Decl(new ID(fmt("helper_%d", ++helper_id_seq)), HELPER),
|
||||
helper_type_(helper_type),
|
||||
context_id_(context_id),
|
||||
code_(code)
|
||||
{
|
||||
}
|
||||
|
||||
HelperDecl::~HelperDecl()
|
||||
{
|
||||
delete context_id_;
|
||||
delete code_;
|
||||
}
|
||||
|
||||
void HelperDecl::Prepare()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void HelperDecl::GenExternDeclaration(Output *out_h)
|
||||
{
|
||||
if ( helper_type_ == EXTERN )
|
||||
code_->GenCode(out_h, global_env());
|
||||
}
|
||||
|
||||
void HelperDecl::GenCode(Output *out_h, Output *out_cc)
|
||||
{
|
||||
Env *env = global_env();
|
||||
|
||||
#if 0
|
||||
if ( context_id_ )
|
||||
{
|
||||
Decl *decl = Decl::LookUpDecl(context_id_);
|
||||
if ( ! decl )
|
||||
{
|
||||
throw Exception(context_id_,
|
||||
fmt("cannot find declaration for %s",
|
||||
context_id_->Name()));
|
||||
}
|
||||
env = decl->env();
|
||||
if ( ! env )
|
||||
{
|
||||
throw Exception(context_id_,
|
||||
fmt("not a type or analyzer: %s",
|
||||
context_id_->Name()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( helper_type_ == HEADER )
|
||||
code_->GenCode(out_h, env);
|
||||
else if ( helper_type_ == CODE )
|
||||
code_->GenCode(out_cc, env);
|
||||
else if ( helper_type_ == EXTERN )
|
||||
; // do nothing
|
||||
else
|
||||
ASSERT(0);
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
#ifndef pac_decl_h
|
||||
#define pac_decl_h
|
||||
|
||||
#include "pac_common.h"
|
||||
#include "pac_id.h"
|
||||
|
||||
class Decl : public Object
|
||||
{
|
||||
public:
|
||||
// Note: ANALYZER is not for AnalyzerDecl (which is an
|
||||
// abstract class) , but for AnalyzerContextDecl.
|
||||
enum DeclType { ENUM, LET, TYPE, FUNC, CONN, FLOW, ANALYZER, HELPER, REGEX };
|
||||
|
||||
Decl(ID *id, DeclType decl_type);
|
||||
virtual ~Decl();
|
||||
|
||||
const ID *id() const { return id_; }
|
||||
DeclType decl_type() const { return decl_type_; }
|
||||
AnalyzerContextDecl *analyzer_context() const
|
||||
{ return analyzer_context_; }
|
||||
|
||||
// NULL except for TypeDecl or AnalyzerDecl
|
||||
virtual Env *env() const { return 0; }
|
||||
|
||||
virtual void Prepare() = 0;
|
||||
|
||||
// Generate declarations out of the "binpac" namespace
|
||||
virtual void GenExternDeclaration(Output *out_h) { /* do nothing */ }
|
||||
|
||||
// Generate declarations before definition of classes
|
||||
virtual void GenForwardDeclaration(Output *out_h) = 0;
|
||||
|
||||
virtual void GenCode(Output *out_h, Output *out_cc) = 0;
|
||||
|
||||
void TakeExprList();
|
||||
void AddAttrs(AttrList *attrlist);
|
||||
void SetAnalyzerContext();
|
||||
|
||||
protected:
|
||||
virtual void ProcessAttr(Attr *a);
|
||||
|
||||
ID *id_;
|
||||
DeclType decl_type_;
|
||||
AttrList *attrlist_;
|
||||
ExprList *expr_list_;
|
||||
AnalyzerContextDecl *analyzer_context_;
|
||||
|
||||
public:
|
||||
static void ProcessDecls(Output *out_h, Output *out_cc);
|
||||
static Decl *LookUpDecl(const ID *id);
|
||||
|
||||
private:
|
||||
static DeclList *decl_list_;
|
||||
typedef map<const ID *, Decl*, ID_ptr_cmp> DeclMap;
|
||||
static DeclMap decl_map_;
|
||||
};
|
||||
|
||||
class HelperDecl : public Decl
|
||||
{
|
||||
public:
|
||||
enum HelperType {
|
||||
HEADER, CODE, EXTERN,
|
||||
};
|
||||
HelperDecl(HelperType type, ID *context_id, EmbeddedCode *code);
|
||||
~HelperDecl();
|
||||
|
||||
void Prepare();
|
||||
void GenExternDeclaration(Output *out_h);
|
||||
void GenForwardDeclaration(Output *out_h) { /* do nothing */ }
|
||||
void GenCode(Output *out_h, Output *out_cc);
|
||||
|
||||
private:
|
||||
HelperType helper_type_;
|
||||
ID *context_id_;
|
||||
ID *helper_id_;
|
||||
EmbeddedCode *code_;
|
||||
|
||||
static int helper_id_seq;
|
||||
};
|
||||
|
||||
#endif // pac_decl_h
|
|
@ -1,82 +0,0 @@
|
|||
#include "pac_id.h"
|
||||
#include "pac_primitive.h"
|
||||
#include "pac_output.h"
|
||||
|
||||
#include "pac_embedded.h"
|
||||
|
||||
EmbeddedCodeSegment::EmbeddedCodeSegment(const string &s)
|
||||
: s_(s), primitive_(0)
|
||||
{
|
||||
}
|
||||
|
||||
EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive *primitive)
|
||||
: s_(""), primitive_(primitive)
|
||||
{
|
||||
}
|
||||
|
||||
EmbeddedCodeSegment::~EmbeddedCodeSegment()
|
||||
{
|
||||
delete primitive_;
|
||||
}
|
||||
|
||||
string EmbeddedCodeSegment::ToCode(Env *env)
|
||||
{
|
||||
if ( primitive_ && s_.empty() )
|
||||
s_ = primitive_->ToCode(env);
|
||||
return s_;
|
||||
}
|
||||
|
||||
EmbeddedCode::EmbeddedCode()
|
||||
{
|
||||
segments_ = new EmbeddedCodeSegmentList();
|
||||
}
|
||||
|
||||
EmbeddedCode::~EmbeddedCode()
|
||||
{
|
||||
delete_list(EmbeddedCodeSegmentList, segments_);
|
||||
}
|
||||
|
||||
void EmbeddedCode::Append(int atom)
|
||||
{
|
||||
current_segment_ += static_cast<char>(atom);
|
||||
}
|
||||
|
||||
void EmbeddedCode::Append(const char *str)
|
||||
{
|
||||
current_segment_ += str;
|
||||
}
|
||||
|
||||
void EmbeddedCode::Append(PacPrimitive *primitive)
|
||||
{
|
||||
if ( ! current_segment_.empty() )
|
||||
{
|
||||
segments_->push_back(new EmbeddedCodeSegment(current_segment_));
|
||||
current_segment_ = "";
|
||||
}
|
||||
segments_->push_back(new EmbeddedCodeSegment(primitive));
|
||||
}
|
||||
|
||||
void EmbeddedCode::GenCode(Output *out, Env *env)
|
||||
{
|
||||
if ( ! current_segment_.empty() )
|
||||
{
|
||||
segments_->push_back(new EmbeddedCodeSegment(current_segment_));
|
||||
current_segment_ = "";
|
||||
}
|
||||
|
||||
// TODO: return to the generated file after embedded code
|
||||
// out->print("#line %d \"%s\"\n", line_num, filename.c_str());
|
||||
|
||||
// Allow use of RValue for undefined ID, in which case the
|
||||
// ID's name is used as its RValue
|
||||
env->set_allow_undefined_id(true);
|
||||
|
||||
foreach(i, EmbeddedCodeSegmentList, segments_)
|
||||
{
|
||||
EmbeddedCodeSegment *segment = *i;
|
||||
out->print("%s", segment->ToCode(env).c_str());
|
||||
}
|
||||
|
||||
env->set_allow_undefined_id(false);
|
||||
out->print("\n");
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef pac_embedded_h
|
||||
#define pac_embedded_h
|
||||
|
||||
#include "pac_common.h"
|
||||
|
||||
class EmbeddedCodeSegment
|
||||
{
|
||||
public:
|
||||
explicit EmbeddedCodeSegment(const string &s);
|
||||
explicit EmbeddedCodeSegment(PacPrimitive *primitive);
|
||||
~EmbeddedCodeSegment();
|
||||
|
||||
string ToCode(Env *env);
|
||||
|
||||
private:
|
||||
string s_;
|
||||
PacPrimitive *primitive_;
|
||||
};
|
||||
|
||||
typedef vector<EmbeddedCodeSegment *> EmbeddedCodeSegmentList;
|
||||
|
||||
class EmbeddedCode : public Object
|
||||
{
|
||||
public:
|
||||
EmbeddedCode();
|
||||
~EmbeddedCode();
|
||||
|
||||
// Append a character
|
||||
void Append(int atom);
|
||||
void Append(const char *str);
|
||||
|
||||
// Append a PAC primitive
|
||||
void Append(PacPrimitive *primitive);
|
||||
|
||||
void GenCode(Output *out, Env *env);
|
||||
|
||||
private:
|
||||
string current_segment_;
|
||||
EmbeddedCodeSegmentList *segments_;
|
||||
};
|
||||
|
||||
#endif // pac_embedded_h
|
|
@ -1,70 +0,0 @@
|
|||
#include "pac_exception.h"
|
||||
#include "pac_enum.h"
|
||||
#include "pac_expr.h"
|
||||
#include "pac_exttype.h"
|
||||
#include "pac_output.h"
|
||||
#include "pac_typedecl.h"
|
||||
|
||||
Enum::Enum(ID* id, Expr* expr)
|
||||
: id_(id), expr_(expr)
|
||||
{
|
||||
}
|
||||
|
||||
Enum::~Enum()
|
||||
{
|
||||
delete id_;
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
void Enum::GenHeader(Output* out_h, int *pval)
|
||||
{
|
||||
ASSERT(pval);
|
||||
if ( expr_ )
|
||||
{
|
||||
if ( ! expr_->ConstFold(global_env(), pval) )
|
||||
throw ExceptionNonConstExpr(expr_);
|
||||
out_h->println("%s = %d,", id_->Name(), *pval);
|
||||
}
|
||||
else
|
||||
out_h->println("%s,", id_->Name());
|
||||
global_env()->AddConstID(id_, *pval);
|
||||
}
|
||||
|
||||
EnumDecl::EnumDecl(ID *id, EnumList *enumlist)
|
||||
: Decl(id, ENUM), enumlist_(enumlist)
|
||||
{
|
||||
ID *type_id = id->clone();
|
||||
datatype_ = new ExternType(type_id, ExternType::NUMBER);
|
||||
extern_typedecl_ = new TypeDecl(type_id, 0, datatype_);
|
||||
}
|
||||
|
||||
EnumDecl::~EnumDecl()
|
||||
{
|
||||
delete_list(EnumList, enumlist_);
|
||||
delete extern_typedecl_;
|
||||
}
|
||||
|
||||
void EnumDecl::Prepare()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void EnumDecl::GenForwardDeclaration(Output *out_h)
|
||||
{
|
||||
out_h->println("enum %s {", id_->Name());
|
||||
out_h->inc_indent();
|
||||
int c = 0;
|
||||
foreach(i, EnumList, enumlist_)
|
||||
{
|
||||
(*i)->GenHeader(out_h, &c);
|
||||
++c;
|
||||
}
|
||||
out_h->dec_indent();
|
||||
out_h->println("};");
|
||||
}
|
||||
|
||||
void EnumDecl::GenCode(Output* out_h, Output* /* out_cc */)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef pac_enum_h
|
||||
#define pac_enum_h
|
||||
|
||||
#include "pac_decl.h"
|
||||
|
||||
class Enum
|
||||
{
|
||||
public:
|
||||
Enum(ID *id, Expr *expr = 0);
|
||||
~Enum();
|
||||
|
||||
void GenHeader(Output *out_h, int *pval);
|
||||
|
||||
private:
|
||||
ID *id_;
|
||||
Expr *expr_;
|
||||
};
|
||||
|
||||
class EnumDecl : public Decl
|
||||
{
|
||||
public:
|
||||
EnumDecl(ID *id, EnumList *enumlist);
|
||||
~EnumDecl();
|
||||
|
||||
Type *DataType() const { return datatype_; }
|
||||
|
||||
void Prepare();
|
||||
void GenForwardDeclaration(Output *out_h);
|
||||
void GenCode(Output *out_h, Output *out_cc);
|
||||
|
||||
private:
|
||||
EnumList *enumlist_;
|
||||
Type *datatype_;
|
||||
TypeDecl *extern_typedecl_;
|
||||
};
|
||||
|
||||
#endif // pac_enum_h
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue