Compare commits

...
681 Commits
Author SHA1 Message Date
Ulya Trofimovich 349a97c831 CMake: create output directory before building docs.
Previously trying to run rst2man.py with an output file in a nonexistent
directory resulted in the following build error:

  $ cmake --preset=linux-gcc-debug-ootree-skeleton-full
  $ cmake --build --preset=linux-gcc-debug-ootree-skeleton-full
  ...
  [  1%] Generating src/msg/help.cc
  Unable to open destination file for writing:
    OutputError: [Errno 2] No such file or directory:
      '[...]/linux-gcc-debug-ootree-skeleton-full/src/msg/help.cc.1'
2021-11-28 16:38:51 +00:00
Ulya Trofimovich e07052b566 CMakePresets.json: inherit "full" configuration before "fast".
Otherwise variable definitions from "fast" configuration take precedence
over the "full" configuration, resulting in disabling some important
configrations, such as Go language support.

For example, if "fast" is inherited before "full" we have the following
incorrect configrations that sets RE2C_BUILD_RE2GO:BOOL="FALSE":

  $ cmake -S .. --preset=linux-gcc-release-ootree-skeleton-full
  Preset CMake variables:

    CMAKE_BUILD_TYPE="Release"
    CMAKE_CXX_COMPILER="g++"
    CMAKE_C_COMPILER="gcc"
    CMAKE_INSTALL_PREFIX:PATH="[CUT]/re2c/install"
    RE2C_BUILD_LIBS:BOOL="TRUE"
    RE2C_BUILD_RE2GO:BOOL="FALSE"
    RE2C_FOR_BUILD="[CUT]/re2c/install/bin/re2c"
    RE2C_REBUILD_DOCS:BOOL="TRUE"
    RE2C_REBUILD_LEXERS:BOOL="TRUE"

But if "full" is inherited after "fast" we have the following (correct):

  $ cmake -S .. --preset=linux-gcc-release-ootree-skeleton-full
  Preset CMake variables:

    CMAKE_BUILD_TYPE="Release"
    CMAKE_CXX_COMPILER="g++"
    CMAKE_C_COMPILER="gcc"
    CMAKE_INSTALL_PREFIX:PATH="[CUT]/re2c/install-2"
    RE2C_BUILD_LIBS:BOOL="TRUE"
    RE2C_BUILD_RE2GO:BOOL="TRUE"
    RE2C_FOR_BUILD="[CUT]/re2c/install/bin/re2c"
    RE2C_REBUILD_DOCS:BOOL="TRUE"
    RE2C_REBUILD_LEXERS:BOOL="TRUE"
2021-11-28 16:38:51 +00:00
Ulya Trofimovich 8a4772cee8 Make --loop-switch work with conditions.
Merge all conditions in one loop/switch where DFA for each condition has
its own set of cases. Use `yystate` variable to switch between
conditions in the same way as between DFA states.

The => rules set user-defined condition variable with YYSETCONDITION.
The :=> rules set `yystate` and continue to the head of the loop/switch.
2021-11-27 00:05:53 +00:00
Ulya Trofimovich b031e27437 Respect define:YYGETSTATE:naked configuration in loop/switch mode. 2021-11-26 23:15:51 +00:00
Ulya Trofimovich c643db456c For skeleton and .dot targets merge header file into the output file.
Header file may contain blocks with regular expressions and rules. They
should be handled as well as the blocks in the output file.

This patch fixed a failing skeleton test.
2021-11-22 23:53:15 +00:00
Ulya Trofimovich dcbbd01055 Use initial state indices as condition numbers with --loop-switch.
Normally with the goto/label approach condition enumeration uses
implicit consecutive indices starting from zero. With the loop/switch
approach it is more convenient to represent conditions with their
initial DFA state index. This allows one to assign condition numbers to
the state variable `yystate` and get rid of the entry condition switch.
2021-11-21 21:41:26 +00:00
Ulya Trofimovich d2cf8a37e9 Factor out block list construction into a separate function. 2021-11-21 20:42:02 +00:00
Ulya Trofimovich c5179da5f8 Delay YYMAXFILL / YYMAXNMATCH computation until handling the directive.
The `maxfill:re2c` and `maxnmatch:re2c` directives may specify an
optional list of block names. If the list is specified, the directives
compute maximum value over the specified blocks, otherwise they compute
global maximum across all blocks in the program.

Previously the global maximum was prepared in advance even if the
directives were not used. This patch delays the computation of global
YYMAXFILL / YYMAXNMATCH until they are needed, as is already done in
the case when the directive specifies a list of blocks.
2021-11-21 17:57:20 +00:00
Ulya Trofimovich 4edb6ca2d9 Delay global tag list construction until handling the directive.
The `stags:re2c` and `mtags:re2c` directives may specify an optional
list of block names. If the list is specified, the directives gather
condition nems from the specified blocks, otherwise they use a global
set of tag names gathered across all blocks.

Previously the global set was prepared in advance even if the directives
were not used, but a set for specific block list was constructed only if
needed. This patch delays global set construction until it is needed and
unifies it with the case of a specific block list.
2021-11-21 10:36:35 +00:00
Ulya Trofimovich 8b93728f93 Do not autogenerate condition enum if there is an explicit types:re2c.
The rationale is, if the user specified an explicit `types:re2c`
directive, they probably do not want the autogenerated enum as well. If
for some reason they need multiple enum definitions (either in the
output file or in the header file), they can use multiple `types:re2c`
directives.
2021-11-21 10:04:13 +00:00
Ulya Trofimovich e551a4918b Search for named blocks both in the output file and in header.
This fixes a test for condition enum: previously re2c emitted an error
because one of the `types:re2c` directives listed block name for a block
defined in another file, and re2c failed to find it. Now it finds it.
2021-11-21 09:44:50 +00:00
Ulya Trofimovich 51f769133b Do not generate empty condition enum.
Some compilers or language standards allow it, but generally it's more
likely to indicate an error in user code.

Fix a few tests that generated empty condition enum by mistake.
2021-11-21 09:41:31 +00:00
Ulya Trofimovich df50c25fc3 Clean up old tests for condition enum and header.
Replace a bunch of simple and similar tests with a few more
comprehensive ones that cover recent re2c features like named blocks and
block lists in the `types:re2c` directive, in addition to older features
such as the --type-header option.

One of the new tests reveals an error in re2c: it fails to find
conditions in header. The error will be fixed in a follow-up commit.
2021-11-21 09:41:31 +00:00
Sergei Trofimovich ac672c9ce4 avoid using reserved identifiers (underscores)
clang with -Weverything detects these as:

    ./src/util/free_list.h:9:16:
      warning: identifier '_Ty' is reserved
      because it starts with '_' followed by a capital letter [-Wreserved-identifier]
    template<class _Ty>
                   ^
2021-11-17 22:52:30 +00:00
Sergei Trofimovich 59edd763bf fix struct/class declaration mismatch (-Wmismatched-tags)
Detected by clang's-Weverything:

    ./src/regexp/re.h:17:1: warning: struct 'Msg' was previously declared as a class;
      this is valid, but may result in linker errors under the Microsoft C++ ABI [-Wmismatched-tags]
    struct Msg;
    ^
2021-11-17 22:52:02 +00:00
Ulya Trofimovich 66c6b1cd96 Make --loop-switch work with storable state.
With the loop/switch approach there is no `goto` statement, so it is
impossible to jump from a `getstate:re2c` block to an YYFILL label,
bypassing all the user-defined code in the middle (as it normally
happens with the goto/label approach).

Therefore `getstate:re2c` is forbidden with --loop-switch, and the
initial switch on storable state is merged into the `yystate` switch:

  - case -1 falls through to case 0 (the initial state)

  - transitions to YYFILL states are moved to cases that occupy
    contiguous numbers after the last regular DFA state

In order to make it possible to wrap the generated lexer in a
user-defined loop, an `YYSETSTATE(1)` statement is emitted in each final
state before the user-defined semantic action: if the action jumps to
the head of the outer loop, the next iteration will start from state -1,
as the user might expect. Note that `YYSETSTATE(1)` is not needed with
goto/label approach, because one can jump directly to the start label.
2021-11-17 21:26:48 +00:00
Ulya Trofimovich e42b3db26a Make --loop-switch and --eager-skip options non-configurable.
Having configuration for the --loop-switch option is only useful if one
needs to enable loop/switch approach on a per-block basis. Mixing the
two approaches (goto/label and loop/switch) would mean that some of the
blocks have start labels and can use cross-block transitions, while
others cannot. This would create confusion for whole-program directives
like `getstate:re2c` that cover multiple blocks.

With the loop/switch approach `getstate:re2c` should be forbidden, as it
requires a cross-block transition from the state switch to the lexer
entry, which is unsupported in the absence of the `goto` statement.
2021-11-16 07:32:01 +00:00
Ulya Trofimovich 1def5f1874 With --loop-switch, start state enumeration from zero in each block.
Normally with the goto/label approach re2c uses a program-wide state
enumeration that starts from zero and increases with each block. Since
each state has a label, global enumeration allows one to have multiple
blocks in the same function without the risk of label collision.
Moreover, different blocks can be connected with cross-block `goto`
transitions, so all state labels should have different numbers.

The situation is different with the loop/switch approach: there are no
labels and no cross-block `goto` transtions; instead every state has a
switch on the `yystate` variable. Since different block have different
switches, it makes sense to start state enumeration from zero in each
block (so that switch cases start from zero, and the zeroth case
corresponds to the start state of every block).
2021-11-14 18:54:37 +00:00
Ulya Trofimovich 29d6adcee1 Drop useless -c option in some of the Go examples.
These examples do not use conditions, so -c does nothing. It has been
accidentally copy-pasted from another example that uses conditions.
2021-11-09 23:08:44 +00:00
Ulya Trofimovich 81feecfbfe Add tests for the new --loop-switch option (for C and Go backends).
The added tests are copy-pasted from examples, but the generated code is
different: it uses loop/switch constructs instead of goto/label. All
tests except for conditions and storable state are valid programs that
can be compiled and run without errors.
2021-11-09 23:02:21 +00:00
Raekye a03b3b4d54 Initial implementation of the --loop-switch option.
With this option, instead of the usual goto/label approach DFA is
wrapped in a loop with a `switch` statement on `yystate` variable. Each
DFA state is an individual `case`. Transitions between states are done
by setting the `yystate` variable to the numeric index of the target
state and executing `continue` that jumps to the head of the loop and
goes via the `switch` again. This is less efficient than direct jumps
with the goto/label approach, but it is the only way we can implement a
DFA for languages that do not have `goto` statement (such as Rust).

YYFILL labels are problematic for the loop/switch approach, because they
are normally in the middle of a DFA state (after the YYSKIP operation,
but before YYPEEK and transitions to other states). To fix this, we use
the --eager-skip option that moves YYSKIP operations from DFA states to
transitions.

The initial value of `yystate` is the numeric index (label) of the first
DFA state. It is _not_ the intiial label, because initial label does not
have a state (so there is no `case` in the `switch` for it), and it is
only needed to bypass YYSKIP operation in the first DFA state (which is
not there anyway because of the --eager-skip option).

Current limitations:
  - Conditions are not supported. We need a per-condition `yystate`, and
    ideally transitions between conditions should also use a loop/switch
    approach instead of goto/label (it will be required for Rust, but it
    is optional for C and Go).

  - Storable state is not supported. We need to rewrite user-defined
    code to use the same state variable as `yystate` and the one in
    `YYGETSTATE`/`YYSETSTATE`, as well as to put `getstate` block
    immediately before DFA entry (if there is any code between state
    dispatch and DFA entry, it needs to be bypassed when re-entering
    the lexer after YYFILL, which is easily done with goto/label
    approach in C and Go, but not in Rust that has no `goto`).

Test results with the --loop-switch option enabled by default:
  - Skeleton tests pass (320 soft errors).

  - Examples for C and Go compile and run without errors, except for
    conditions, storable state and cases when user-defined code needs to
    be rewritten (e.g. when it uses an outer loop and `continue`/`break`
    statements end up referring to the wrong loop).
2021-11-09 21:54:48 +00:00
Raekye 10f84e73ed Don't generate initial label if --eager-skip option is used.
The initial label is not needed in such cases as there is no need to
bypass YYSKIP statement (--eager-skip moves it from states to
transitions).
2021-11-09 21:54:48 +00:00
Raekye bddcb93fa9 Add stubs for --loop-switch option and related configurations.
The following has been added:
  - option --loop-switch
  - configuration `re2c:flags:loop-switch`
  - configuration `re2c:variable:yystate`

Currently they are no-ops.
2021-11-09 21:54:48 +00:00
Raekye 1c8451883f Move --eager-skip option from constant to mutable.
This is necessary to support the future --loop-switch option.

With --loop-switch we cannot have labels (goto targets) in the middle of
a state. This affects YYFILL labels which normally go after YYSKIP but
before YYPEEK. The --eager-skip option resolves the problem by moving
YYSKIP statements from states to transitions. The plan is to enforce it
automatically if --loop-switch is enabled, but since --loop-switch will
be a mutable option, --eager-skip also needs to be mutable.
2021-11-09 21:54:48 +00:00
Raekye e3e76b0fe4 Skeleton: use goto-loop instead of for-loop.
To support the future --loop-switch option, this change avoids
unexpected control flow with `continue`.

The skeleton tests are verified and updated.
2021-11-09 21:54:48 +00:00
Ulya Trofimovich 68e1ab7160 Correctly compute fixed tags in trailing context.
Tags in trailing context may be fixed on the rightmost cursor position.
Their values must be updated before cursor is reset to the position of
the trailing context, otherwise the values would be incorrect.
Previously this was not so, which resulted in incorrect tag values.

This fixes bug #380 "Tags incorrectly set with lookahead" reported by
Terry Sanders .
2021-11-04 23:51:01 +00:00
Ryan Mast 8920ef895b Setup Java for the benchmarks workflow using actions/setup-java 2021-11-02 07:25:00 +00:00
Perry E. Metzger 73dc6295a7 minor fixes to interface.rst_
Improve grammar, make some small style improvements, and keep the
lines consistently under 80 columns. Also update boostrap docs for
resulting changes.
2021-10-31 20:30:35 +00:00
Ulya Trofimovich 6d7c3cbb47 Small fixes in distcheck script.
Changes:
  - use 'sh' instead of 'bash' as interpreter
  - split build into stages 1 and 2 and rebuild lexers at stage 2
  - double-quote shell variables to make shellcheck happy
2021-10-24 13:10:47 +01:00
Ulya Trofimovich 072d49e59c Autotools: link google-benchmark binaries with pthread. 2021-10-22 16:52:36 +01:00
Ulya Trofimovich eb8720d5ea Use unsigned integers for register versions in TDFA states.
Previously we used negative numbers for register versions that were
allocated for transitions on negative tags. This is pointless, because
state mapping may biject positive versions to negative ones or vice
versa, erasing the distinction. And it wasn't used anyway.
2021-09-15 22:42:55 +01:00
Ulya Trofimovich b90b78c79c Mark each register as not interfering with itself.
Exclude diagonal pairs from interference table. This does not affect
subsequent register allocation, because the algorithm that partitions
registers into non-interfering classes does not check is a register
interferes with itself. So the fix does not affect the generated code,
except for one test that draws the interference table.
2021-09-04 09:41:08 +01:00
Ulya Trofimovich 6b434e934c run_tests.py: make tests fast again by fixing Wine check.
Commit ec1dc2b3ec incorrectly compared
Wine path against `None` to determine if the tests run under Wine. That
doesn't work as expected because the default value is empty string, not
`None`, so the checks always succeeded and as a result the script did
unnecessary work (patched newlines in the generated output). That made
it a few times slower.
2021-09-04 09:16:04 +01:00
Biswapriyo Nath 15376f4393 Define _POSIX_SOURCE for fdopen in cygwin
This fixes the error:
error: ‘fdopen’ was not declared in this scope; did you mean ‘fopen’?
2021-09-03 16:35:42 +01:00
Serghei Iakovlev dff1b6cd36 Provide support of CMake Presets
Since 3.19.8 CMake looks in the top source directory of a project for files
named CMakePresets.json and CMakeUserPresets.json. Neither file is required
to be present, but if the user tries to list or use presets, at least one of
the files must exist. If both files are present, they will effectively be
merged by reading the CMakePresets.json file first and then the
CMakeUserPresets.json file.

CMakePresets.json can be used to define presets for things like continuous
integration jobs or cross-compilation setups using toolchains provided as
part of the project. In general this feature allows us to simplify CI
configuration phase by taking out all the logic into presets-file and helps
us to make reproducible builds. From now on, you no longer need to carefully
read and copy all the flags locally in order to reproduce CI configuration or
build. Simple use the same one line command as at CI.

As a bonus, users of modern CMake can use a cross-platform and portable way
instead of build/__cmake*.sh scripts.

To see the list of available presets use:
    cmake --list-presets

To configure re2c use:
    cmake --preset=<NAME>

To build re2c use:
    cmake --build --preset=<NAME>

To test re2c use:
    cmake --build --preset=<NAME> --target tests

References:

- https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
- https://gitlab.kitware.com/cmake/cmake/-/issues/21164
- https://cmake.org/cmake/help/latest/guide/user-interaction/index.html#presets
2021-08-12 12:30:44 +01:00
Ulya Trofimovich aa2da70299 Release 2.2. 2021-08-01 10:05:50 +01:00
Ulya Trofimovich cf13205c63 Update CHANGELOG. 2021-08-01 08:34:40 +01:00
Ulya Trofimovich ec1dc2b3ec run_tests.py: patch newlines under Wine and get rid of Wine warnings. 2021-07-31 20:42:52 +01:00
Ulya Trofimovich a9ba2c4d91 Add forgotten includes to make headers self-contained. 2021-07-31 20:42:52 +01:00
Ulya Trofimovich 36e4a0e5ee run_tests.py: use a local reimplementation of shutil.copytree.
We need to copy multiple directories (test/ and examples/) into one
(temporary test directory). `shutil.copytree` is problematic for two
reasons:

 1) it requires `dirs_exist_ok` parameter which was added only in
    python-3.8

 2) `make distcheck` fails when trying to copy the second directory
    because it makes source files read-only
2021-07-31 09:10:28 +01:00
Ulya Trofimovich a779585cb3 split_man.sh: allow substitution RE2C_LANG_NAME -> {C,Go}. 2021-07-31 09:10:28 +01:00
Ulya Trofimovich 53ee23a54f Update docs: rewrite the introduction section of the manual. 2021-07-25 21:13:51 +01:00
Ulya Trofimovich 477f35b567 Travis CI: use Ubuntu 20.04 (Focal Fossa) to have Python 3 by default. 2021-07-25 11:08:03 +01:00
Ulya Trofimovich 1d84bb9816 Update Travis CI config. 2021-07-25 10:25:54 +01:00
Ulya Trofimovich f67f489281 Simplify interface code in Go tests with re2c:api:style = functions;. 2021-07-24 13:15:15 +01:00
Ulya Trofimovich 0bd2b72155 Add BUILD.md with build/test instructions. 2021-07-18 18:57:05 +01:00
Ulya Trofimovich 423c56ca55 Update documentation for directives. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 58f47cd066 Use new re2c features in re2c lexers to have some real-world coverage. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich fd2e96394f Slightly relax !use and !include directive format.
- allow optional spaces before the semicolon
- allow whitespace or the end of block after the semicolon (previously
  only a newline was allowed)
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 2a973270d9 Don't fail when meging symtabs with pointer-identical name definitions.
This may happen if a name is defined in global scope and inherited by a
`rules:re2c` block that is followed by another block that uses the rules
block with a `!use` directive:

  /*!re2c
      x = [x];
  */

  /*!rules:re2c:R
      // inherits 'x' definition from global scope
      y = [y];
  */

  /*!re2c
      // inherits 'x' definition from global scope
      // imports the same 'x' definition from 'R'
      !use:R;
  */

At the time when symtab from the rules block is merged with the
inherited one, there is a collision on the global names that are present
in both symtabs. It's harmless.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich a20d8965a9 Unify handling of getstate:re2c with other directives. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich a096166f83 Allow 'format' and 'separator' configuration in types:re2c.
Now it is possible to customize this directive:

  /*!types:re2c
      format = "static const int @@{cond} = @@{num}";
      separator = "\n";
  */
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 19be0e3ab7 Unify #line info for directives max, maxnmatch, stags, mtags.
Tests have been updated because `#line` directives are now generated in
more cases than previously.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 144dbc4146 Unify handling of directives max, maxnmatch, stags, mtags. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 7262325fbe Move the definition of codegen block kinds to constants.h. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 6bfd78133e Move constant definitions to a top-level header to reduce dependencies.
Also, add and remove a few files.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 92b98e9781 Deprecate configurations flags:i and flags:no-debug-info.
Global options `-i` and `--no-debug-info` can be used instead.

Configurations allow to enable/disable `#line` directives on a more
fine-grained basis (for selected parts of the file), but there's not
much point in doing so and there are no known real-world use cases.
Having them as global options is convenient, because a global option
can be used in parser (unlike a configuration, which can change and for
which the final value is unknown until the whole block is parsed).
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 7c278733fa Clean up a few places in codegen that have to use global options.
The few places are:
  - condition enum (this one should always use whole-program options)
  - state switch (this one should either use whole-program options, or
    block-local options if this is a `use:re2c` block

Add comments.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 02da15a2ef Store block pointer in codegen context instead on inlining its fields. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 2d1aec19ba Handle block lists in types:re2c directive. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 958ac86e51 Use block-specific condition prefix when generating condition enum. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich ca0ebe9c58 Handle block lists in stags:re2c and mtags:re2c directives. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 20236a1b04 Skeleton: emit global m-tag definitions only once (to avoid collisions). 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 43b6533936 Allow 'format' configuration in max:re2c and maxnmatch:re2c.
Now it is possible to customize these directives:

  /*!max:re2c
      format = "static const int YYMAXFILL = @@";
  */

  /*!maxnmatch:re2c
      format = "static const int YYMAXNMATCH = @@";
  */

This commit breaks backward compatibilty, because it forbids arbitrary
garbage at the end of `max:re2c` directive. It was historically allowed
and even used in one test, but it doesn't add any practical value and
it's getting in the way of adding 'format' option (or any other option).
The following code that was previously accepted now triggers an error:

  /*!max:re2c
      ... arbitrary g4rbage ...
  */
2021-07-17 21:38:36 +01:00
Ulya Trofimovich fa8e24f844 Pass struct to functions to reduce the number of parameters. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich e1fc740020 Split 1st pass codegen context into global and block-local parts. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich d91e137ca0 Handle block lists in maxnmatch:re2c directive. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 9383114bd6 Handle block lists in max:re2c directive. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 78c77ab417 Rename test subdirectory. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich d81c2ecd4e Point at the beginning of a block in warnings and error messages. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich ac4aaed276 Forbid duplicate names in block lists.
For example, emit an error on `/*!getstate:re2c:x:y:x */`. Previously
this resulted in code that would not compile (due to duplicate cases in
the generated state switch), but an explicit error message from re2c
is more user-friendly (and it covers all block lists, not just the case
of `getstate:re2c` directive).
2021-07-17 21:38:36 +01:00
Ulya Trofimovich ba7eec131c Forbid blocks to have identical names (including autogenerated ones). 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 480010a043 Append block number to autogenerated block name.
Previously autogenerated names were identified by block line, but it may
be non-unique (it is possible to have multiple blocks on the same line,
included files may define blocks at the same line, and line directives
may reset line number).
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 62ef4235cf Add tests for state switch (with -f --storable-state option). 2021-07-17 21:38:36 +01:00
Ulya Trofimovich f2fb9ac94c Improve error reporting when generating state switch.
Emit error messages instead of failing debug checks when:
- there are no blocks with code in the global state switch
- first named block on the list is empty (has no start label)
- a named block is missing (reworked error message)

Also, rewrite the code in a way that avoids looping over the block list
twice. Previosuly the first loop was used to to find a start label, and
the second loop was to generate switch cases. Now we do both in the same
loop and prepend the default case with the start label to other cases.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 89841a7a23 Split "expand" code generation pass into first and second passes.
The first pass expands everything except labels (they have to wait until
the second pass because the first pass may generate some additional uses
for previously unused labels). The second pass expands labels.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 93d39f384d Rework codegen for state switch with -f --storable-state option.
State switch is generated differenly for `use:re2c` blocks and for all
other blocks.

For use blocks there is a block-local switch that is automatically
generated at the beginning of the block. Previously use blocks had a
separate enumeration of YYFILL states starting from zero, and they used
a block-specific prefix in YYFILL state labels. Now use blocks
participate in the global YYFILL state enumeration, and their labels no
longer require a block-specific prefix (because label numbers are unique
across the whole file).

For all other blocks there is a global state switch that is generated
either at the point where `getstate:re2c` directive is specified by the
user, or (if there are no user-defined `getstate:re2c` directives) at
the beginning of the first non-use block that has a start label. Code
generation of the global state switch hasn't changed.

Now it has become possible to generate a state switch for the subset of
blocks specified in a `getstate:re2c` directive. The code is still
slightly incorrect, as the start label for the first block on the list
is not always generated (only if this block is the first non-use block
in the file). This happens because the generation of labels happens too
early, before the generation of the state switch that marks the start
label as used.

The tests that have use blocks have been updated (only the labels and
the autogenerated YYFILL state numbers have changed).

As a result of this patch the cases in a state switch no longer have to
start from zero and be sequential: 0, 1, 2,... . Now they can start with
any number and consist of block-local sequential ranges (the numbers are
unique and non-decreasing). State numbering is an internal re2c detail,
so it should not affect any users. State -1 (or any other negative
number) is handled in the same way as before (as a special case).

To facilitate the generation of state switch based on block names, the
code has been rewritten to find blocks by their name. Each block now
stores start and end YYFILL indices and a link to the start label. This
information is used in the generation of state switch instead of an
implicit assumption that indices start from zero and occupy sequential
numbers. Use blocks are also handled via the new name-based mechanism:
they use a special autogenerated block name which is passed to the
autogenerated block-local state switch.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 410c81e060 Give all input blocks a name (a user-defined or an autogenerated one). 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 703af40334 Rename input block enum and move it to a header with fewer dependencies. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich ac2c9ff132 Always count start label with -f --storable-state option.
Start label is not always used, only in cases when there is a transition
to the start state or if it is explicitly enforced by the user.

Previously re2c did not include start label in the global label
enumeration unless it was actually generated. This required knowing in
advance if the label was used or not. Currently we do have such
knowledge, because the default transition in the state switch goes to
the first block in the file (except for reuse blocks, which have
individual state switch).

But this is problematic for the new `getstate:re2c` that is allowed to
specify a list of block names, because the default transition now needs
to go to the first block on the list, not the first block in the file.

This commit adds start label to the global label enumeration, even if it
is not generated. As a result, label numbers in some tests have changed.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich f502e54357 Allow generating user-defined state switch multiple times. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 0ae6ed4675 Allow specifying block names in re2c blocks and directives.
Don't do anything with the specified names yet, just parse them and save
for future use. Follow-up changes will handle block names for each type
of block or directive.

The following block types now have an optional name:

    /*!re2c[:name] ... */
    /*!local:re2c[:name] ... */

The following directives now have an optional list of colon-separated
block names:

    /*!max:re2c[:name1[:name2...]] ... */
    /*!maxnmatch:re2c[:name1[:name2...]] ... */
    /*!types:re2c[:name1[:name2...]] ... */
    /*!getstate:re2c[:name1[:name2...]] ... */
    /*!stags:re2c[:name1[:name2...]] ... */
    /*!mtags:re2c[:name1[:name2...]] ... */
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 15cc78861a Add local blocks (declared with /*!local:re2c ... */).
The new type of blocks differs from the usual `/*!re2c ... */` blocks
in that the names and configurations it defines are local: they have the
scope of a block and aren't visible outside of it in the global scope.
This allows one to reuse the same names multiple times in different
blocks, and to avoid "polluting" the global scope.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich ac5a710548 Use correct symbol table for each block.
Symbol table (a.k.a. the mapping of named definitions to regexps) should
obey the same scoping rules as configurations. Before this commit it was
broken: there was one global symbol table that accumulated all named
definitions along the way.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 8d97e4b5be Make run_tests.py executable on UNIX (lost when migrating to python). 2021-07-17 21:38:36 +01:00
Ulya Trofimovich 2c4d5c8c06 run_tests.py: don't pass nonexistent parameter to function. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich b6c96f92ea run_tests.py: don't crash if some expected output files are missing. 2021-07-17 21:38:36 +01:00
Ulya Trofimovich ae4e534bc8 run_tests.py: don't crash when reference results are missing.
Run tests to the end and produce results for all test cases that are
missing reference results. This is convenient when adding new tests, as
it allows one to drop *.re files in the test directory, run the tests
(failure is expected), manually verify the generated results and copy
them to the test directory.
2021-07-17 21:38:36 +01:00
Ulya Trofimovich 88ff1e5a2a run_tests.py: patch newlines and backslashes in test results on windows. 2021-06-27 16:23:28 +01:00
Ulya Trofimovich c581194f7a Properly escape backslashes in the generated file paths.
Add escaping in some previously forgotten cases.

Avoid double escaping (previously this happened for some include files
for which file path was constructed as a concatenaton of an already
escaped directory part and the yet unescaped file path in the include
directive).

This only affects platforms that use backslashes in file paths (such as
Windows).
2021-06-27 16:23:28 +01:00
Ulya Trofimovich ad98410b00 run_tests.py: skip overflow-1 on windows (failing due to small stack). 2021-06-27 16:23:28 +01:00
Ulya Trofimovich ebfd61a3db Rewrite recursion into iteration for stats function.
This helps to avoid overflow on systems with small stack.
2021-06-27 16:23:28 +01:00
Ulya Trofimovich c4be6d05d3 run_tests.py: fix tests on Wine.
This fixes `make wtests` (--wine option to run_tests.py).

A few things were broken:
  - re2c binary should have '.exe' file extension
  - `re2c --version` on wine is rather slow, so drop the 2s timeout
2021-06-27 16:23:28 +01:00
Ulya Trofimovich 0ea48c905e GitHub Actions CI: unmask Windows tests. 2021-06-27 16:23:28 +01:00
Ulya Trofimovich b8a47acfa1 GitHub Actions CI: upload test build directory, not source directory. 2021-06-27 16:23:28 +01:00
Sergei Trofimovich d363c06980 configure.ac: allow user to set non-standard PYTHON
Useful on systems with multiple python implementations.
While at it allow both 'python3' (preferred) and 'python' spellings.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2021-06-24 23:36:05 +01:00
Ulya Trofimovich e7d43c7655 Use unique names for header files generated by the tests.
Header files may be created in the same directory, so that one header
overwrites the other. It also causes races in run_tests.py when it tries
to clean up intermediate files created by each test.
2021-06-22 23:38:46 +01:00
Serghei Iakovlev beb0fe59bb Make remove() function simpler
The previous version of this function has multiple responsibilities and
actually had knowledge for which it was not intended.

These changes are about "S" in SOLID.
2021-06-20 22:24:00 +03:00
Ulya Trofimovich 3e14320a87 run_tests.py: don't shard tests, use chunk size 1.
Previously the script divided all tests into chunks of equal size, which
is suboptimal as different tests take different time, and often large
tests end up in the same chunk. This adds imbalance and makes the test
runner slower than it could be with chunk size 1.

Also, use a more pythonic way to gather results from threads. The old
bash script did that via per-thread log files because it is hard to do
it otherwise in bash. But in python one can simply return results from
each thread, avoiding the overhead on file I/O.
2021-06-20 15:59:38 +01:00
Ulya Trofimovich 75881ab9c6 Remove an old useless test that revealed races in run_tests.py.
The removed test was a trivial modification of another test (with -i
option turned off). It was useful long ago, but not anymore as we have
many tests with or without -i option.

The removed test was problematic because it created a header file with
the same name as the other test, which revealed a race in test runner
that removed the generated header before the other file processed it.

This got uncovered while debugging run_test.py, when I changed
multiprocessing.Pool.map() to multiprocessing.Pool.imap(). The race
happened only once in a few runs.
2021-06-20 15:59:38 +01:00
Serghei Iakovlev 43025a8793 Run regular tests under Windows
These changes are intended to prepare the project to run tests under
Windows.  Currently Windows tests are disabled until we dealing with
failures.
2021-06-20 10:59:58 +01:00
Ulya Trofimovich 60773997a6 Update information about #re2c IRC channels.
After the downfall of freenode #re2c channel has migrated to OFTC and
Libera.Chat.
2021-06-19 21:24:32 +01:00
Serghei Iakovlev 9c9981190b Rewrite re2c test runner in Python
This pull request introduces a completely rewritten test runner
in Python.

The main goals of this change:

- Provide a OS-independent way to run tests (at least using CMake)
- Getting rid of dependence on Unix utilities in tests
  (grep, cat, tr, etc.)
- Flexibility
- Ease of maintenance
2021-06-19 14:20:35 +01:00
Serghei Iakovlev cf57858bce Add step names to benchmark workflow 2021-06-16 00:23:40 +01:00
Ulya Trofimovich 150b2d38b1 benchmarks.yml: quote Python version to prevent parsing it as float. 2021-06-16 00:23:40 +01:00
Ulya Trofimovich 5de6ae6328 run_tests.sh: bring back --keep-tmp-files option.
This reverts commits:
  - ec9eecd077
  - f710983c23

By default if some tests fail, the corresponding temporary files are
kept (for investigation). For the passing tests temporary files are
removed. But in some cases it is convenient to keep temporary files for
the passing tests as well.
2021-06-15 22:49:17 +01:00
Ulya Trofimovich f710983c23 run_tests.sh: remove obsolete '--keep-temp-files' option from help.
Note: the option itself was removed in commit
ec9eecd077, but the obsolete description
remained until now.
2021-06-15 08:51:23 +01:00
Ulya Trofimovich 424dfed352 Submatch Java benchmark: update REgen submodule. 2021-06-15 07:53:22 +01:00
Ulya Trofimovich 3dce73623c Submatch Java benchmark: account for varying RE size within each group.
REgen procduces input data with variable RE size within each group, so
in order to generate truthful plot it is necessary to take that variance
into account.

For JS plot, compute the x-coordinate as the average RE size withing
each group (also average the y-coordinate within each group, as before).

For PGF plot, don't average RE size, instead use individual RE size as
the x-coordinate. Do a few transformations on the benchmark results:
remove outliers using centered moving median, then smooth the curve
using centered moving average.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich ff6382b5bc Submatch Java benchmark: copy JS chart to the build directory.
It is a runtime dependency of ReTdfa.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich 6dbaae39bd Submatch Java benchmark: add a small samples file (zipped). 2021-06-15 07:53:22 +01:00
Ulya Trofimovich f8f10c201a Submatch Java benchmark: add REgen as a Git submodule.
REgen is a program that generates input data for the benchmark. We use a
fork of the original repo in order to be able to apply local patches.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich 82623c3e8c json2pgfplot.py: escape backslash when generating TeX code. 2021-06-15 07:53:22 +01:00
Ulya Trofimovich f70d5a8364 Java submatch benchmark: generate PGF plot. 2021-06-15 07:53:22 +01:00
Ulya Trofimovich 0f63fed70d Submatch DFA AOT benchmark (run script): fail if output file is not set.
Exception is verification mode, when there is no need to log output.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich e60fbdcc8f Submatch DFA JIT benchmark: drop leftmost greedy variants.
Although leftmost greedy results are different from POSIX ones, the
relative difference of register/registerless variants is similar, so
it suffices to keep only the POSIX variants.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich 80b3249e00 Remove the old build script for ReTdfa benchmark. 2021-06-15 07:53:22 +01:00
Ulya Trofimovich a38f46396d GitHub Actions (benchmarks workflow): add ReTdfa benchmark. 2021-06-15 07:53:22 +01:00
Ulya Trofimovich 2c1b39cff0 Add Makefile.am for the ReTdfa benchmark.
The benchmark is built if configure option --enable-benchmarks is set
and environment variable JAVA_HOME is non-empty.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich 9079ce8614 Add CMakeLists.txt for the ReTdfa benchmark.
The benchmark is built if configuration option RE2C_BUILD_BENCHMAKRS has
been set and CMake is able to find Java.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich 25d881dc2a Add regular expression library and benchmark by Angelo Borsotti.
ReTdfa is a Java library that contains a family of algorithms for
regular expression parsing and submatch extraction based on TNFA and
TDFA. It is also a benchmark for various algorithms, including some
that are based on libre2c.

This commit also adds Java bindings to libre2c.
2021-06-15 07:53:22 +01:00
Ulya Trofimovich c15ef2d410 libre2c: don't allocate/free memory for pmatch[] in the library.
This should be done by the user, and the library may only store a
pointer to the allocated memory in the regex_t structure (this is
convenient for the foreign bindings).
2021-06-15 07:53:22 +01:00
Ulya Trofimovich 6fe4df03ae libre2c: do not include project-local headers in regex.h.
The regex.h header is included by the users of the library. Including
other local headers in it is problematic, because the user then has to
specify additional include search paths (and do so by trial and error
rather than by some general rule).

Strictly speaking, this commit breaks C++98 compatibility as <stdint.h>
is non-standard in C++98. But in practice this is unlikely to cause any
problem, as libre2c is a recently added experimental library which
hardly has any users that do not have a C++11 toolchain.
2021-06-15 07:53:22 +01:00
Serghei Iakovlev 4a89dc2d6e Speedup CI workflow by removing not used cache step 2021-06-13 21:13:17 +01:00
Ulya Trofimovich 7f27352602 Better handling of syntax errors in re2c directives.
- Fail with an error in some confusing cases like
  `/*!include:re2c x.re */` that are likely to be unintentional syntax
  errors (double quotes missing around the filename), but previously did
  not fail and were treated like comments (no code was generated).

- Improve error messages for syntax errors such as a bad block name.

AFL tests had to be updated, because the original tests that crashed the
lexer now fail earlier due to an unrelated reason, so a space character
had to be added in some tests to make them hit the same error as before.
2021-05-28 12:16:45 +01:00
Ulya Trofimovich 536f097936 Update docs regarding precedence of special rules in reused blocks. 2021-05-28 00:18:55 +01:00
Ulya Trofimovich 11af1f43c7 Allow overriding special rules inherited from reusable blocks.
Within one block special rules *, $ and <!> cannot be redefined (it is
an error). However, when reusing other blocks it might be convenient to
override inherited special rules with local ones. This commit separates
inherited and local special rules by storing them in separate containers
that are merged at the end.

Also, this commit merges functions that validite and "normalize"
specifications into one function. This has to be done because some of
the validation checks must be performed before merging special rules,
and some must be done after that.
2021-05-28 00:18:55 +01:00
Ulya Trofimovich db641794fd Update documentation and add more examples for reusable blocks. 2021-05-28 00:18:55 +01:00
Ulya Trofimovich 4fff2e35fb Enable reuse blocks by default and deprecate -r, --reusable option.
Now that `/*!rules:re2c ... */` and `/*!use:re2c ... */` blocks can be
mixed freely with the ordinary `/*!re2c ... */` blocks, there is no
reason not to allow reuse mode by default.
2021-05-28 00:18:55 +01:00
Ulya Trofimovich 4f8adcb3cc Clean up data structures that represent reuse blocks.
Also, fix memory leak in the parser (found by LeakSanitizer): don't
forget to free std::string that was allocated to hold block name in the
inline `!use` directive.
2021-05-28 00:18:55 +01:00
Ulya Trofimovich 261a4b91ed Disallow garbage at the end of directives (with a few exceptions).
Historically re2c allows arbitrary text before the closing comment of
the directives such as `/*!ignore:re2c ... */` and `/*!max:re2c ... */`.
It only makes sense for the ignore directive (which is just a multiline
comment), but not for other directives. This commit disallows garbage at
the end of all directives, except `/*!ignore:re2c ... */` and (for the
reasons of backward compatibility) `/*!max:re2c ... */`.
2021-05-28 00:18:55 +01:00
Ulya Trofimovich 2262fe7dbe Don't forget to adjust line count after inline !include directive. 2021-05-28 00:18:55 +01:00
Ulya Trofimovich 7e66ba5334 Add inline !use directive.
The inline `!use:<block-name>;` directive  can be used in the middle of
a re2c block. It allows one to merge a block named <block-name> into the
currect block: rules of the used block are added to the current set of
rules, and configurations are added to the current options. Overlapping
rules and configuraitons have the usual priority, as if the used block
was literally inserted in place of the `!use` directive (the first rule
wins, and the last configuration wins).
2021-05-28 00:18:55 +01:00
Ulya Trofimovich ee37e0f03f Initial implementation of named blocks.
Named blocks allow one to reuse any rules block, not only the last one.
The syntax named blocks extends existing syntax for unnamed blocks:

    /*!rules:re2c:<name>
        ...
    */

An optional name is specified after a semicolon. The block can then be
used by specifying its name in a use block:

    /*!use:re2c:<name>
        ...
    */
2021-05-28 00:18:55 +01:00
Ulya Trofimovich 867cf7522c Update docs and examples for the inline include directive. 2021-05-21 08:55:34 +01:00
Ulya Trofimovich cb6d9025ad Allow include directives in the middle of a block.
This commit addresses issue #351 "include directive limitations",
reported by Henry Harvey.

An include directive in the middle of a block is useful in cases when
the include file contains additional rules overlapping with the rules in
the including file. In such cases the usual directive won't work, as it
would crate a new re2c block with its own set of rules (rather than
merge the included rules into the current set).

The inline directive syntax is slightly different from the usual re2c
directive syntax: comment markers '/*' and '*/' are dropped to avoid
nested multiline (which are unsupported in C/C++), and the ':re2c' part
is also dropped because it is redundant (the inline directive is already
inside of a re2c block).
2021-05-21 08:55:34 +01:00
Ulya Trofimovich db219561ec libre2c: add option REG_AUTOTAGS that enables full parsing mode.
The new option automatically adds tags for all subexpressions, as if
they were wrapped in capturing parentheses. This is only useful for
experimental purposes (to measure parsing speed in the case of fully
tagged RE and study performace degradation of different algorithms as
the density of submatch increases).
2021-05-12 23:39:51 +01:00
Ulya Trofimovich a703a46586 libre2c: use t-string fragments instead of trie for regless algorithms.
Unwinding tag history from its trie representation is rather slow. This
can be done in advance at regcomp() time, and the resulting t-string
fragments can be stored in backlinks (this is what regtstring() already
uses). For offset construction t-string fragments also need to include
negative tags.
2021-05-11 22:43:34 +01:00
Ulya Trofimovich 62fe269e84 libre2c: use common forward pass for all regless-TDFA algorithms.
The forward pass is the same for regexec(), regparse() and regtstring().
2021-05-10 09:12:00 +01:00
Ulya Trofimovich 44611fe7f8 libre2c: add some comments for regparse() and regtstring(). 2021-05-10 09:12:00 +01:00
Ulya Trofimovich 478fe2576a libre2c: add an algorithm that constructs a t-string.
This CL adds a new flag REG_TSTRING and a new API function regtstring()
that returns a t-string (a flattened representation a parse tree where
characters of the input string are interleaved with tags).

The goal of this algorithm is to construct parse results in the cheapest
possible way. There is no standard representation of a parse tree, and
any nontrivial representation would likely incur a significant overhead
(the algorithm would spend most of the time constructing parse results
rather doing the actual parsing).

The t-string representation requires very little effort to construct,
provided that the t-string fragments corresponding to the tagged paths
in the epsilon-closure are prepared in advance at regcomp() time. The
fragments are stored as arrays of tags, so that they can be easily
copied to the resulting t-string. Importantly, this does not require
unwinding of tag history stored in a trie form, which is rather slow.

A t-string is represented as a sequence of 16-bit values that are either
ASCII characters (that occupy the lower byte, leaving the higher byte as
zero) or tags (that are numeric value shifted to the upper half of the
16-bit range).

16-bit size for t-string characters is chosen to align with the
experimental Java implementation by Angelo Borsotti.

T-string allocation is done on the library side, and the t-string is
stored in the regexp structure. The user gets an immutable view of the
resulting t-string and is not expected to free memory after calling
regtstring(). Moreover, the library reuses the same memory on each
regtstring() call and reallocates it only if the new t-string does not
fit into the old memory area.

All in all, the new regtstring() API is primarily intended for
benchmarking the speed of the parsing algorithms, and not for "official"
use.
2021-05-10 09:12:00 +01:00
Ulya Trofimovich 308b434e1d libre2c: add algorithms for submatch extraction on all repetitions.
This patch adds a new flag REG_SUBHIST and new API functions regparse()
and regfreesub().

regparse() returns parse results as an array of nmatch size, where each
element is an array of offset pairs for the correspoinding capturing
group. If a group has matched repeatedly at different parts of the input
string, then its array will contain multiple offset pairs; otherwise, a
single pair. This differs from the standard POSIX API, where onl the
last offset pair for each group is returned.

The allocation of memory for the parse results is done by the library
(the user cannot know how much memory will be needed). The ownership of
parse results is transferred to the user, who is expected to deallocate
memory allocated by regparse() with regfreesub().
2021-05-10 09:12:00 +01:00
Ulya Trofimovich e3d5973eb6 libre2c: don't forget to set fallback tags in regexec_dfa.
In order to do that, it is necessary to compute fallback states and
insert fallback tags.
2021-05-10 09:12:00 +01:00
Alexander Shemetovskiy 58b5e89439 Fix link to CONTRIBUTING.md 2021-04-26 00:00:53 +01:00
Ulya Trofimovich b1d3afe144 Rename directory for SIMPA article. 2021-04-06 07:30:42 +01:00
Ulya Trofimovich 07e417fa94 Fix typo in documentation (add missing space). 2021-04-05 10:25:45 +01:00
Ulya Trofimovich 1ae96895a8 CMake: pass re2c options for benchmark as two distinct arguments.
Otherwise the build fails with error:
    re2c: error: bad long option: --no-generation-date --no-version
2021-04-04 10:18:33 +01:00
Ulya Trofimovich b4efac3cc0 Add benchmark results on April 2, 2021.
The measurements have been taken on an Intel(R) Core(TM) i7-8750H CPU
with 32 KiB L1 Data cache (x6 cores), 32 KiB L1 Instruction cache (x6
cores), 256 KiB L2 Unified cache (x6 cores), 9216 KiB L3 Unified cache,
32 GiB RAM.

Software versions:
- ragel-7.0.4
- kleenex built from Git at commit d474c60
- re2c built from Git at commit 1c3bead
- re2-2020-11-01
- GCC-10.2.0
- Clang-11.0.0
2021-04-02 11:50:50 +01:00
Ulya Trofimovich 1c3bead790 Benchmarks: update ragel to 7.0.4 (and update autogenerated files). 2021-04-02 11:10:51 +01:00
Ulya Trofimovich a13d86491e Benchmarks: create directory for kleenex before building it. 2021-04-02 11:10:51 +01:00
Ulya Trofimovich b55ab37a22 Generate benchmarks with --no-version to avoid updates on every release. 2021-04-01 23:51:20 +01:00
Ulya Trofimovich 042cf6b671 json2pgfplot.py: fix accidentally swapped 'symbols' and 'captures'.
Also, take care of the singular/plural form.
2021-04-01 23:51:20 +01:00
Ulya Trofimovich 116873e30a json2pgfplot.py: use 'fixed relative' number format.
It reduces the visual noise on the plot: there are no exponents, but
the number of printed decimal places depends on the magnitude. In
combination with very high precision and some custom code that rounds
fractional part but keeps integer part intact, this allows one to have
numbers that are not too precise, but not too rounded either.

This format also has the advantage that it does not need math font, so
fonts like Comic Neue that don't have math support can be used as well.
2021-04-01 23:51:20 +01:00
Ulya Trofimovich 1177560f5e json2pgfplot.py: add option --font <comicneue | cmbright>.
The new option allows one to select the font to be used in the generated
PGF plot. Currently the supported fonts are 'comicneue' (Comic Neue) and
'cmbright' (Computer Modern Bright).
2021-04-01 23:51:20 +01:00
Sergei Trofimovich 1b402b0e88 configure.ac: avoid bash-specific '==' comparison
In https://bugs.gentoo.org/779187 Matt noticed errors when running ./configure
on dash:
    ./configure: 5339: test: x: unexpected operator
    ./configure: 5386: test: x: unexpected operator

The change is to use POSIX '=' comparison instead of bash-specific ==.

Patch-by: Matt Whitlock
Bug: https://bugs.gentoo.org/779187
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2021-03-31 22:09:44 +01:00
Ulya Trofimovich 568d4226f7 Move variable initialization before goto statement.
This is to avoid compiler errors on Solaris 10, see #347.
2021-03-29 07:57:50 +01:00
Ulya Trofimovich 342e53a71e Release 2.1.1. 2021-03-27 18:28:33 +00:00
Ulya Trofimovich a609454ebe Update CHANGELOG for release 2.1.1. 2021-03-27 18:23:13 +00:00
Ulya Trofimovich a051e673de Distcheck: test that release tarball can be built with CMake.
This is to prevent bugs like #346 "No CMakelists.txt file in new 2.1
release".
2021-03-27 18:16:32 +00:00
Ulya Trofimovich 27f42a454d Add CMakeLists.txt to release tarballs.
It was accidentally dropeed from EXTRA_DIST in commit
9959efed38. This was reported in #346
"No CMakelists.txt file in new 2.1 release".
2021-03-27 15:05:08 +00:00
Ulya Trofimovich ddae31d386 Release 2.1. 2021-03-26 19:11:47 +00:00
Ulya Trofimovich 9c9bf9decd Move EXTRA_DIST under WITH_BENCHMARKS to fix basic bmake distcheck.
`bmake distcheck` still fails with the same error if configured with
`--enable-benchmarks`, but now at least in the basic configuration it
succeeds. The error with `--enable-benchmarks` is:

  Making distclean in benchmarks/submatch_nfa
  bmake[2]: "[.]/re2c-2.0.3/_build/sub/benchmarks/submatch_nfa/Makefile"
            line 407: Could not find ./.deps/bench_submatch_nfa-bench.Po
  bmake[2]: Fatal errors encountered -- cannot continue
2021-03-26 18:57:52 +00:00
Ulya Trofimovich bf9003445e Update CHANGELOG for release 2.1. 2021-03-26 17:41:37 +00:00
Ulya Trofimovich a8d540d2ef GitHub Actions CI: add -m32 build with GCC on Linux.
A recent commit bf5b965384 fixed an error
specific to build environments which have 32-bit size_t. It was not
captured by CI because the CI didn't use 32-bit builds on Linux/macOS,
and it didn't run tests on Windows (which has 32-bit size_t).
2021-03-26 09:44:53 +00:00
Ulya Trofimovich ecf2d186b7 GitHub Actions: let unused compiler flags default to an empty string. 2021-03-26 09:44:53 +00:00
Ulya Trofimovich 2d78364f02 GitHub Actions CI: remove obsolete workaround for arguments with spaces. 2021-03-26 09:44:53 +00:00
Ulya Trofimovich b0eebb06b4 GitHub Actions CI: fix shell quoting to allow spaces in CMake arguments.
Use printf to quote array elements when expanding them to a string, or
when passing as arguments to CMake.
2021-03-26 09:44:53 +00:00
Ulya Trofimovich 3b933dc360 Add missing include (fixes build error on Fedora). 2021-03-26 09:37:25 +00:00
Ulya Trofimovich bf5b965384 Fix error in 32-bit mode (in fixed tags optimization).
The error was in setting a constant to ~0u and comparing it to another
constant of type size_t, defined as std::numeric_limits<size_t>::max().
In 64-bit mode these are different values, but in 32-bit mode they are
the same, which triggered errors in the algorithm that finds fixed tag
candidates. The error manifested as a lot of broken tests.
2021-03-25 07:36:55 +00:00
Ulya Trofimovich 8e4d8d2431 Remove obsolete build scripts for LSan (it is integrated into ASan). 2021-03-25 07:36:55 +00:00
Ulya Trofimovich f9d5825021 Add missing includes to make header self-contained. 2021-03-25 07:36:55 +00:00
Ulya Trofimovich 8139571a16 Remove similar cases in submatch DFA JIT benchmark. 2021-03-25 07:36:55 +00:00
Ulya Trofimovich 5470d6613f Drop fractional part in timings for submatch DFA AOT benchmarks.
They normally take hundreds of milliseconds to run, so the fractional
part doesn't matter and it clutters the output.
2021-03-25 07:36:55 +00:00
Ulya Trofimovich bcc5674f96 Clean up data generation scripts for submatch DFA AOT benchmarks.
Replace them all with a small python script that copy-pastes small
sample enough times to fill 100M file.
2021-03-25 07:36:55 +00:00
Ulya Trofimovich 5f81b48a80 Rework submatch DFA AOT benchmarks for repetition.
Changes:
  - give benchmarks more descriptive names
  - make the first benchmark triple in the "rep" series use multiple
    tags and the same counters as the other triples
2021-03-25 07:36:55 +00:00
Ulya Trofimovich 85f3bcaea2 Drop Kleenex patch, as the upstream has been fixed. 2021-03-25 07:36:55 +00:00
Ulya Trofimovich 3f0d6cc220 Rename submatch DFA AOT benchmarks (to enforce order and group by name).
Prefix all benchmarks with a number, where the first digit is the group
index (e.g. all "real-world" benchmarks start with 0), and the second
digit is the index of a benchmark inside group. Now it is possible to
run a selected subset of benchmarks, e.g. all "real-world" benchmarks:

  $ ./run.py --filter '^0'
2021-03-25 07:36:55 +00:00
Ulya Trofimovich 6a1666bc29 benchmarks/submatch_dfa_aot/run.py: interpret filters as regexps. 2021-03-25 07:36:54 +00:00
Ulya Trofimovich 3256099620 Rename submatch DFA AOT benchmarks for re2c (to avoid "-bc" suffix).
re2c benchmarks use two different end-of-input handling methods: the
default bounds checking method, and the more recent $-rule method based
on `re2c:eof` configuration. Although it is interesting to compare their
performance, presenting both methods on the plots makes them too
cluttered (and the performance of the two methods is similar compared to
other algorithms and lexer generators). So one of them is chosen as
primary (bounds checking) and its suffix "-bc" is dropped to simplify
labels on the plots.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich 46a2cdeac0 json2pgfplot.py: change --relative option to --relative-to <name>.
The new option requires passing (part of) a name of the algorithm to be
used as a base for normalizing other algorithms.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich 2d626ebe7f json2pgfplot.py: make dots at the end of cropped columns more visible. 2021-03-25 07:36:54 +00:00
Ulya Trofimovich 7e13a453bd json2pgfplot.py: better handling of plot limits.
Don't cut off parts of the plot because of too-small limits: set limits
based on the number of bars in each individual plot, and use "ymax" and
"ymin" to specify exact limits (rather than the previously used
"enlarge y limits" setting).
2021-03-25 07:36:54 +00:00
Ulya Trofimovich 14d8b56dab json2pgfplot.py: choose scale based on the global average and maximum.
Compute maximum bar length ("xmax") based on the global average and
maximum values among all benchmarks. This is to avoid cases when a very
long bar dominates other bars and makes them appear too small. Such
outliers are cropped and marked with "..." to show that they overflow.
Previously the corring was done only in "relative" mode, because in
"absolute" mode it was unclear how to choose "xmax" value. Now that
"xmax" is computed based on global average and maximum, cropping is used
in both "relative" and "absolute" modes.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich 389ad6d086 json2pgfplot.py: optionally plot binary size in addition to CPU time.
Also add binary size plots to benchmarks/submatch_dfa_aot/run.py.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich 2863e5431f json2pgfplot.py: allow JSON input w/o "regsize" and "captures" fields.
For DFA AOT submatch benchmarks we do not know the number of captures or
the regular expression size. In principle they could be extracted from
the generated file (for re2c only), or an option could be added to the
programs to print statistics (for re2c and ragel, but not kleenex, as it
autogenerates the program and the user controls only the regexp). But it
would be still problematic, as different engines have slightly different
regexps and ways to mark submatch positions.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich a6b82aceb0 json2pgfplot.py: use uniform scale regardless of --relative option.
Uniform scale means that there is a global scale (a common maximum value
shared by all benchmarks). Previously this was used only in "relative"
mode, when all algorithms of a given benchmark are normalized by the
first algorithm. Now it is also used in "absolute" mode.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich f5a2515afd Add verification options to benchmarks/submatch_dfa_aot/run.py.
The new options are:
    --verify       verify parse results on full data files
    --quickverify  verify parse results on small data samples

Replace the old verification script verify.sh with run.py.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich 3f969f8726 Rewrite benchmarks/submatch_dfa_aot/run.sh in Python.
Also, add options `--output <JSON file>` (to generate JSON output in a
form accepted by json2pgfplot.py) and `--filter-out <word>` (to mask
some of the benchmarks). The new script run.py can be used as follows:

  $ ./run.py -h
  usage: run.py [-h] [--output OUTPUT] [--filter FILTER]
                [--filter-out FILTER_OUT] repcount

  positional arguments:
    repcount         number of times to run one benchmark

  optional arguments:
    -h, --help       show this help message and exit
    --output OUTPUT  JSON file to write benchmark results to
    --filter FILTER  pattern to select a subset of benchmarks by name
    --filter-out FILTER_OUT
                     pattern to mask a subset of benchmarks by name
2021-03-25 07:36:54 +00:00
Ulya Trofimovich df89452946 json2pgfplot.py: allow intermixing benchmark groups in the input.
Previously the script grouped benchmarks with the same name together
only if they appeared sequentially in the input file, so that all
benchmarks in one group preceded any benchmarks in another group. Now
this restriction is relaxed: benchmarks with the same name are grouped
together regardless of their position.
2021-03-25 07:36:54 +00:00
Ulya Trofimovich eab9cf4347 json2pgfplot.py: add a comment about expected JSON format. 2021-03-25 07:36:54 +00:00
Ulya Trofimovich 5873e77359 Separate compilation and linking steps in submatch_dfa_aot build.
This is needeed for ccache: it only knows how to cache the compilation
of a single file. Other types of compilations (multi-file compilation,
linking, etc) will silently fall back to running the real compiler.
2021-03-25 07:36:54 +00:00
Sergei Trofimovich 99f85ac1ef src/dfa/dead_rules.cc: move semicolon to a new line
Notice d benign warning when built with clang++ -Weverything:

    src/dfa/dead_rules.cc:205:77: warning: for loop has empty body [-Wempty-body]
        for (; sentcls < nsym && sentsym >= dfa.charset[sentcls + 1]; ++sentcls);
                                                                                ^

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2021-03-12 08:47:11 +00:00
Sergei Trofimovich 42d1b66950 src/skeleton/generate_data.cc: avoid 't' local variable shadow
Noticed when built with clang++ -Weverything:

    src/skeleton/generate_data.cc:325:35:
      warning: declaration shadows a local variable [-Wshadow]
                        const mtag_t &t = tagtrie.head[tval];
                                  ^
    src/skeleton/generate_data.cc:300:21:
      note: previous declaration is here
            for (size_t t = ltag; t < htag; ++t) {
                    ^

Renamed `t` to `mt` to disambiguate.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2021-03-12 08:47:11 +00:00
Sergei Trofimovich 45bc776fb7 src/skeleton/mtag_trie.h: avoid stray semicolon
Noticed when built with clang++ -Weverything:

    ./src/skeleton/mtag_trie.h:67:2: warning:
      empty expression statement has no effect;
        remove unnecessary ';' to silence this warning [-Wextra-semi-stmt]
    {;
     ^

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2021-03-12 08:47:11 +00:00
Ulya Trofimovich 1d826f4dc5 libre2c: add registerless TDFA algorithm.
The idea is to replace registers and register operations with a runtime
log of backlinks that allow to reconstruct the matching TNFA path and
unwind tag history backwards from the final state to the initial state.

As the benchmarks show, on artificial inputs registerless TDFA can be
much faster than TDFA with registers (a few orders of magnitude). On
real-world inputs it is slightly slower (up to 2x).
2021-03-07 14:08:29 +00:00
Ulya Trofimovich 0291d3da83 Correct comments about explicit instantiation of C++ templates.
Previosly the comments erroneously referred to it as "explicit
specialization", which is a different thing.
2021-03-07 14:08:29 +00:00
Ulya Trofimovich 047e61f570 libre2c: make regexec_dfa template depending on automaton type.
This is to avoid runtime overhead on checking which type of actions
should be performed (TDFA or staDFA).
2021-03-07 14:08:29 +00:00
Ulya Trofimovich e7887f8f02 Use 32-bit integers instead of bitfields for tag info.
Bit fields allow packing tag index and tag sign together in one 32-bit
value, which saves space. However it makes re2c slower (approximately
10% on benchmark bench_submatch_nfa/HTTP-RFC7230).
2021-03-07 14:08:29 +00:00
Ulya Trofimovich 4c5d4abdb4 Add a python script for converting benchmark results to a PGF plot.
usage: json2pgfplot.py [-h] [--relative] input output

    positional arguments:
      input       input JSON file
      output      output TeX file

    optional arguments:
      -h, --help  show this help message and exit
      --relative  output CPU time relative to the first algorithm
2021-03-07 14:08:29 +00:00
Ulya Trofimovich 5ef0b746dd Use google/benchmark library for NFA and DFA-JIT benchmarks. 2021-03-07 14:08:29 +00:00
Ulya Trofimovich 117268d681 Add documentation for --depfile option. 2021-03-03 21:29:58 +00:00
Ulya Trofimovich 7000b4788a Add tests for the new --depfile option. 2021-03-03 08:38:40 +00:00
Ulya Trofimovich be9c8dad96 run_tests.sh: support generation of depfiles. 2021-03-03 08:37:19 +00:00
Ulya Trofimovich 33d25eed4e Use the right parent file when opening include files.
Parent file is the one that contains `/*!include:re2c*/` directive, and
it is not necessarily the same as the most recently opened file (parent
file may have multiple include directives, in which case the most recent
file may be the sibling include file, not the parent one). The incorrect
behavior was introduced in 777476b0d8.
2021-03-02 08:32:40 +00:00
Ulya Trofimovich a30aa9fabc Use existing file paths (not just basenames) when generating depfile.
This matters when `--depfile` option is used together with `-I` option,
and include files are not in the current directory.
2021-03-02 07:52:43 +00:00
Ulya Trofimovich 3ba9108047 Add option --depfile <filename> to generate build dependency file.
The new option is similar to GCC or Clang option `-MD -MF <filename>`.
It computes a transitive closure of all files included with
`/*!include:re2c ... */` directives and writes them to the specified
file in the form of a makefile rule:

    <output> : <input1> <input2> ...

The new option requires that the output file is specified (otherwise it
is unclear how to generate dependency rule).
2021-03-01 23:04:00 +00:00
Ulya Trofimovich c189eb7d9d Add lzip to the list of distribution tarballs.
Note: currently .lz tarball is slightly smaller than .xz (1.7M vs 1.9M).
2021-01-22 07:27:49 +00:00
Ulya Trofimovich 9959efed38 Fix make dist: add missing EXTRA_DIST files and remove obsolete ones. 2021-01-22 07:26:37 +00:00
Ulya Trofimovich d6b0a6b5a4 Return simple s-tags example in addition to the complex one with YYFILL. 2021-01-15 08:10:22 +00:00
Ulya Trofimovich 0811fdc0fa Update submatch example to show how tags should be handled by YYFILL.
This is to avoid confusion as in bug #341: "Tag positions are
unexpectedly shifted in buffer refill mode".
2021-01-12 08:32:43 +00:00
Ulya Trofimovich 13e90b1061 Github Actions: add a new workflow for benchmarks.
The new workflow runs once a week or when manually triggered.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 3b58d5d635 Always regenerate re2c benchmarks using the built re2c executable.
For other engines (kleenex and ragel) regeneration is optional (it is
controlled by CMake option RE2C_REGEN_BENCHMARKS and Autoconf option
--enable-benchmarks-regenerate). This is so because it may be
problematic to download and build other engines, and the results may
be hard to reproduce.

For re2c, it makes sense to always see the latest result.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 1c4659a2eb Tweak benchmark parameters to fit it into reasonable time. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich b74f285457 Use ls -s instead of stat -c%s in script to make it work on macOS. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich fd5fc93a1a Remove make invocation from bench_submatch_dfa_aot run scripts. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 5fb972f204 Do not enable debug info (-g) for bench_submatch_dfa_aot benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 5907182c35 CMake: rename target 'benchmarks' to 'bench_submatch_dfa_aot'. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 7d8261419b CMake: add 'all' and 'clean' targets for bench_submatch_dfa_aot.
Override default CMake 'clean' target by setting directory properties
CLEAN_NO_CUSTOM (which prevents removal of all outputs of custom
commands) and ADDITIONAL_CLEAN_FILES (which adds selected files to the
'clean' target). Use the combination of these properties to make the
'clean' target remove autogenerated C code, binaries and data files,
but keep generators (kleenex, ragel).
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 7bbc87a8d8 Hardcode benchmark input data as C strings instead of loading from file.
For libre2c benchmarks (bench_submatch_nfa and bench_submatch_dfa_jit)
the input is not large (unlike bench_submatch_dfa_aot), so it is
possible to hardcode it as C strings. This allows to avoid file I/O,
which is problematic because paths to the input files depend on the
relative location of the source and build directories.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 69b330a36f Move benchmarks build files to subdirectories. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 2d6b807e1b Use Automake silent rules for building submatch benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 38ad7d9abd Drop less interesting variants of submatch benchmarks.
- Drop ragel -T1/-F1 variants, as they are always slower than -G2.
- Drop re2c TDFA(1) with --eager-skip option in order to reduce the
  number of re2c variants (the dropped variant is sometimes better,
  sometimes worse than TDFA(1), but not by much, and not worth having
  a separate variant).
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 9c0088add8 Add build option to turn on/off regeneration of C code for benchmarks.
For Autotools, the option is --enable-benchmarks-regenerate.
For CMake, the option is RE2C_REGEN_BENCHMARKS.

If the option is off (the default), C files for benchmarks are copied
from pre-generated files.

If the option is on, C files are generated with regexp engines.
Pre-generated files are updated. This requires building regexp engines
(kleenex, ragel, re2c), which works at the moment but may easily break
in the future, as it depends on downloading source code from the
internet and building it. Ragel is built from a versioned archive and
needs only a C++ compiler, but kleenex is a haskell program which
requires ghc and cabal (and it also needs patching for the recent ghc).
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 9b19eb70b9 Add nested CMakeLists.txt for bench_submatch_dfa_aot. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich d8ebd66cb2 CMake: add option RE2C_BUILD_BENCHMARKS (off by default). 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 563bc71ea2 Wire bench_submatch_dfa_aot in the toplevel Makefile.am. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 8e456032d7 configure.ac: add option --enable-benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 23b4d00fdd Deduplicate construction of regexps and strings between benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 451a69922b Add submatch_dfa_jit benchmark. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 7413d729ac Prepare to add submatch_dfa_jit benchmark: extract common part with submatch_nfa. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich f32dd899ef Rename bench_libre2c binary to bench_submatch_nfa. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 2f2e612fea Rename internal option --dfa to --nested-negative-tags.
Note: this option is not documented because it does not have a
corresponding command-line switch or configuration.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich e64c9d0d24 Inline small functions tcmd_t::iscopy, tcmd_t::isset, tcmd_t::isadd. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 1182f816b3 Submatch benchmarks: add "iter" series.
It consists of 3 independent subseries ("iter_a", "iter_b", "iter_c")
for artificial regexps with submatch extraction under repetition.

"iter_a" is R(n) = (a{n} #t)*.
"iter_b" is R(m,n,k) = ((a{m}|a{n}|a{k}) #t)*.
"iter_b" is R(m,n,k) = (a{m} #t1)* (a{n} #t2)* (a{k} #t3)*.

Ragel generates incorrect parse results on "iter_b" and "iter_c",
because actions collide and either they happen to often, or if
disambiguation operators <: and ** are used, some actions get removed
while they are still needed.

Kleenex generates very large output (tens of megabytes) for "iter_b"
(infeasible to compile with GCC or Clang on O3), and for "iter_c" it
causes OOM condition.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 5792db469d Submatch benchmarks: add rules to build engines into the Makefile. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich f5d0f6a398 Submatch benchmarks: create output directories before running commands. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 4483245c72 Rename directory submatch_engines -> submatch_dfa_aot. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 86048ea305 Move libre2c benchmark into benchmarks subdirectory. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich a693da7a60 Submatch benchmarks: add "alt" series.
These are artificial benchmarks for concatenation of alternatives. The
regular expression is:

    R(n,k) =
        (@t_{1,1} a_1* @t_{1,2} | ... | @t_{1,2k+1} a_k* @t_{1,2k+2})
        ...
        (@t_{n,1} a_1* @t_{n,2} | ... | @t_{n,2k+1} a_k* @t_{n,2k+2})

For example R(2,2) = (@a1 a* @a2 | @b1 b* @b2)(@a3 a* @a4 | @b3 b* @b4).
The benchmark includes cases R(1,2), R(1,4), R(1,8), R(2,2), R(2,4),
R(2,8), R(4,2), R(4,4), R(4,8).

For Ragel to handle these benchmarks correctly it is necessary to use
left-guarded concatenation <:.

The benchmarks show that sta-DFA performance degrades quickly with
growing n and k parameters.

Kleenex size and sta-DFA performance degrade quickly with increasing
level of nondeterminism (the k-parameter).
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 6631e27250 Submatch benchmarks: rename "ab" series to "cat". 2021-01-06 08:15:44 +00:00
Ulya Trofimovich af6dec06dc Submatch benchmarks: add a filter for known failures.
Current known failures are Ragel benchmarks ab2_4, ab2_8, ab4_2, ab4_4,
ab8_2. They have nondeterministic tags that require multiple tag
variables to store different possible tag values (until nondeterminism
is resolved, one of the values is selected, and the rest are discarded).
Ragel's actions are not designed for that: if two actions modify the
same variable, Ragel places them in some order on the same transition,
and the resulting value will be incorrect.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich c70cdf36f5 Submatch benchmarks: add "ab" series.
These are artificial benchmarks for sequences of 'a' and 'b' symbols
with varying degrees of tag nondeterminism. The regular expression is:

    R(n,k) = @a_1 a* @b_1 a{k} b* ... @a_n a* @b_n a{k} b*

For example, R(2,4) = @a_1 a* @b_1 aaaa b* @a_2 a* @b_2 aaaa b*. The
benchmark includes cases R(2,0), R(2,4), R(2,8), R(4,0), R(4,2), R(4,4),
R(8,0), R(8,1), R(8,2).

Some of the benchmarks in this series cannot be handled correctly by
Ragel due to its lack of support for nondeterministic tags.

Kleenex size and sta-DFA performance degrade quickly with increasing
level of nondeterminism (the k-parameter).
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 3638449eab Submatch benchmarks: group results by compiler. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich d430348a69 Submatch benchmarks: add re2c TDFA(0) variants. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 89b1ad9368 Submatch benchmarks: add re2c variants that use end of input rule $.
The split is implemented by providing two sets of include files (one for
the default bounds checking method, and one for the $-rule method) and
passing different include options when building *-bc and *-eof benchmark
variants.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich f25d116ec1 Submatch benchmarks: build re2c with debug. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 4516e12115 Mark YYFILL as inline in submatch benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 27d90f4911 Some general cleanup in submatch benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 56d141ce52 Define benchmark output utils as macros to ensure they are inlined.
This is necessary in order to minimize the difference in benchmark results
caused by compiler inlining decisions.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich dca35afffb Small optimization in output utils for submatch benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 5a8513d56b Rewrite Ragel submatch benchmarks in a form closer to re2c.
Instead of writing the output on transitions, only set pointers, and do the
actual writing when the whole rule matches.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 3b47d629c5 Submatch benchmarks: fail assertion instead of growing m-tag list.
The list is preallocated to have enough space (usually there are not so many
m-tags). The old behavior can be returned with define GROW_MTAG_LIST.
2021-01-06 08:15:44 +00:00
Ulya Trofimovich 76cd586b35 Add HTTP benchmark for submatch engines (RFC7230 variant). 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 636f464be8 Share common data files between submatch benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich d9162ff5ad Add some submatch extraction into the email benchmark. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 6fcefcdb76 Add HTTP benchmark for submatch engines (simple variant). 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 047cff55a4 Support arbitrary delimiter string in Ragel benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 704a7972f2 Use memcpy instead of a raw loop. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich afcc7c1d38 Add .gitignore for submatch engines benchmark. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich affb06d191 Add URI benchmarks for submatch engines (simple and RFC3986 variants). 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 3d9a228df6 Add IPv4 benchmark for submatch engines. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 5773fdf46a Factor out common parts of the benchmarks. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich abe0e78463 Add Clang-compiled benchmark variants. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich 4228d90e21 Add benchmark for submatch-capable engines (re2c, kleenex, ragel). 2021-01-06 08:15:44 +00:00
Ulya Trofimovich b66eea236c Move TDFA benchmark into subdirectory. 2021-01-06 08:15:44 +00:00
Ulya Trofimovich eeb4978e94 CMake: minor tweaks in comments. 2020-12-30 10:26:00 +00:00
Ulya Trofimovich ee6e6d7eb8 CMake: override CMAKE_CXX_FLAGS in MSVC builds.
Previosuly cmake/Re2cCompilerFlags.cmake always prepended C++ compiler
options to CMAKE_CXX_FLAGS to avoid overriding user-defined options
passed on the command line with -DCMAKE_CXX_FLAGS. They would still be
overridden by build-type specific options in CMAKE_CXX_FLAGS_DEBUG,
CMAKE_CXX_FLAGS_RELEASE and so on, but at least if the user didn't set
any build type, then user-defined options would take proprity.

However, in MSVC builds CMake populates CMAKE_CXX_FLAGS with default
options, making it impossible (or just hard) to distinguish between
default and user options. So, for MSVC we override CMAKE_CXX_FLAGS.

This commit also fixes the order of CMAKE_CXX_FLAGS added by
cmake/Re2cCompilerFlags.cmake: previosuly the order was reversed, as
each flag was preopended individually. Now all flags are accumulated in
an intermediate variable, which is prepeded in one go.
2020-12-30 09:56:01 +00:00
Ulya Trofimovich 616f34e588 Use memcpy instead of strcpy to avoid warning about unsafe behavior. 2020-12-29 22:31:49 +00:00
Eldar Zakirov 0f57ca3668 Enable support of C++ exceptions on MSVC builds. 2020-12-29 22:11:56 +00:00
Eldar Zakirov 637a382761 Fix compliation on Windows (using MSVS) 2020-12-29 17:03:06 +00:00
Tim Gates fd84b69666 docs: fix simple typo, otheriwse -> otherwise
There is a small typo in libre2c_old/examples/compare/compare.h.

Should read `otherwise` rather than `otheriwse`.
2020-12-17 13:53:02 +00:00
Ulya Trofimovich 4135d0c05c run_tests.sh: cleanup temporary files for non-failing skeleton tests. 2020-11-10 23:28:39 +00:00
Ulya Trofimovich f31eb82c67 run_tests.sh: handle negative return codes in skeleton tests. 2020-11-10 23:27:38 +00:00
Ulya Trofimovich ec9eecd077 run_tests.sh: drop the unused --keep-tmp-files option. 2020-11-10 21:44:51 +00:00
Ulya Trofimovich 745f6e3969 Suppress header generation for skeleton and dot targets.
-t, --type-header option has always been disabled for these targets,
but the recently added directive `/*!header:re2c:on*/` enforced header
generation even if the header option was disabled. Now it checks the
target as well.
2020-11-10 07:56:53 +00:00
Ulya Trofimovich b8b107a300 Skeleton: use circular lists instead of vectors with wrap iterators.
This has the benefit of using a custom slab allocator for list elements,
as well as a simplified way of iterating through the elements (no need
to check for the end of sequence and wrap the iterator).
2020-11-10 07:56:53 +00:00
Serghei Iakovlev 3d6789449c Speed up the CMake configuration by avoiding unnecessary checks 2020-11-07 20:56:40 +02:00
Sergei Trofimovich 8eb6e5c35a --skeleton: add 'auto_da_alloc' reference around remove()/fopen() comment
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2020-11-07 12:17:08 +00:00
Ulya Trofimovich 50ac133cc0 Skeleton: use large output buffer to speedup file writes.
This patch speeds up skeleton generation for test/bug128.re by ~1.5x.
Note that `setvbuf(buffer, NULL, _IOFBF, 1024 * 1024);` does not achieve
the same effect (it makes no difference on systems where buffering is
already enabled).
2020-11-05 23:46:25 +00:00
Ulya Trofimovich efc92f64ce Skeleton: reorder loops to speedup data generation for *.input files.
Process each subpath of the multipath separately (instead of iterating
on all subpaths in lockstep). This allows to write data in the output
buffer sequentially.
2020-11-05 08:16:30 +00:00
Sergei Trofimovich 8090a1bd30 skeleton: delete '.input' and '.keys' files before overwriting them
At least on ext4 `open(O_TRUNC); write(); close()` works a lot
slower than `unlink(); open(); write(); close()`.

My speculation is that ext4 has to do non-trivial free block
accounting at `close()` time that were freed by `O_TRUNC`.

Before the patch:

```
$ rm 1.c.line8.input 1.c.line8.keys; time ../re2c bug128.re -o 1.c -Si
real    0m3,011s
user    0m2,091s
sys     0m0,907s

$ time ../re2c bug128.re -o 1.c -Si
real    0m9,506s
user    0m1,708s
sys     0m0,946s
```

After the patch:

```
$ rm 1.c.line8.input 1.c.line8.keys;  time ../re2c bug128.re -o 1.c -Si
real    0m3,785s
user    0m2,615s
sys     0m1,152s

$ time ../re2c bug128.re -o 1.c -Si
real    0m3,570s
user    0m2,348s
sys     0m1,205s
```

It's a 3x speedup.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2020-11-04 13:09:02 +00:00
Ulya Trofimovich 70c45d1390 Skeleton: lift allocation of temporary buffer out of hot function. 2020-11-02 23:33:50 +00:00
Ulya Trofimovich f24f3c78d5 Skeleton: avoid the overhead on computing tags if there aren't any. 2020-11-02 22:42:32 +00:00
Ulya Trofimovich 0edb0f2bc7 Add test for sta-DFA with end-of-input rule $.
The test covers commit a9d582f9d2. Before
that commit re2c would either fail with assertion on the added test (if
it was built in debug mode), or generate incorrect code (with missing
tag operations on fallback transitions).
2020-11-01 10:30:25 +00:00
Serghei Iakovlev 067bd8af61 Use CMAKE_BUILD_TYPE for single-config build types only 2020-11-01 01:42:21 +02:00
Serghei Iakovlev 2a566af834 Ignore autogenerated directories and files
Update .gitignore
2020-11-01 01:42:21 +02:00
Serghei Iakovlev 7a8d57a302 Add '.log' extension for auto generated test logs 2020-11-01 01:42:21 +02:00
Ulya Trofimovich a9d582f9d2 Don't loose sta-DFA tag actions in final states or with disabled YYFILL.
Also, be aware of sta-DFA tag actions when constructing tags on fallback
transition and when printing the automaton with --dump-adfa option.

Commit 56e46545b8 moved in-state tag
operations before YYFILL label in case $-rule is used. It erroneously
suppressed the generation of sta-DFA tag actions in final states or in
case of disabled YYFILL. This commit fixes that mistake and reinstates
sta-DFA tag actions in such cases.
2020-10-31 10:25:19 +00:00
Ulya Trofimovich 4a47dedad2 Skeleton: lift allocation of temporary buffers out of hot function. 2020-10-30 23:24:27 +00:00
Ulya Trofimovich 3eab74d9fd Provide default initialize and copy operations for wrap iterator.
Depending on the STL implementation these operations are required for
vectors of wrap iterators (in particular, push_back() method may require
a default assignment operator).
2020-10-30 07:51:56 +00:00
Ulya Trofimovich 80f364ee3a Skeleton: use trie to store m-tag histories.
Previously tag values were stored in vectors (even thought most of the
tags are s-tags and have only one element in the history). For tests
with many tags this represenation was taking too much space and time
spent on vector initialization.

Now all tag values are stored as scalars (32-bit integers). For s-tags
the value is the offset. For m-tags the value is an index in the tag
trie (a prefix tree of tag histories that is encoded in an array). This
representation is faster and takes less space.

This allows to save space that was previously used for storing
intermediate tag values of tag variables as vectors

This partially fixes #331.
2020-10-30 00:05:41 +00:00
Ulya Trofimovich e8cdf1ded5 Skeleton: reorder loops to speedup data generation.
Process each subpath of the multipath separately (instead of iterating on all
subpaths in lockstep) in order to reduce the size of storage used for the
intermediate tag values. Previously the required storage was a matrix of size
M x N, where M is the width of the multipath and N is the maximum tag variable
number (prior to tag optimizations). Matrix elements are vectors, because some
tags are m-tags (they need to record the full history, not just the last value).
Allocating and initializing the matrix takes a long time. Now the required
storage is a vector of length N. The same storage is reused for all subpaths.

This partially fixes #331.
2020-10-30 00:05:28 +00:00
Ulya Trofimovich 56e46545b8 Move in-state tag operations before YYFILL label if $-rule is used.
If $-rule is used the lexer may need to jump to the YYFILL label to
rescan the current input character after YYFILL supplies more input.
This may cause re-application of tag operations if they are generated
after the YYFILL label, which may produce incorrect results for non-
idempotent tag operations.

In-state tag operations are used either with sta-DFA (where all tag
operations are in-state and there are no on-transition operations), or
when operations on all transitions agree and can be hoisted out of
transitions into the state body.
2020-10-25 11:22:46 +00:00
Ulya Trofimovich 68611a57a9 Disallow hoisting non-idempotent operations with end-of-input rule $.
If end-of-input rule $ is used, the lexer may need to rescan the current
input character after a successful return from YYFILL. Therefore any
operations that are hoisted out of transitions into the state body may
be re-applied. This is fine as long as the operations are idempotend
(subsequent application produces the same results).

Skip operation is not idempotent, because it increments the cursor every
time it is applied. This is only a problem with --eager-skip option, as
otherwise skip takes place before YYFILL label.

Tag operations may be idempotent or not, depending on whether the tags
used on the right hand side are also used on the left hand side of some
operations (eg 'x = y; y = z;' is non-idempotent because it overwrites
y).
2020-10-25 10:11:01 +00:00
Ulya Trofimovich f41a597bf5 Rename a few tests according to the options they use. 2020-10-24 19:34:21 +01:00
Ulya Trofimovich 2b363b949c GitHub Actions: run skeleton tests after normal tests in the same build. 2020-10-21 08:08:53 +01:00
Serghei Iakovlev 5ec13d6381 Complete CI implementation using CMake and GitHub Actions 2020-10-21 01:00:56 +03:00
Ulya Trofimovich 016a4b0bf7 Regenerate manpages and help.
This update contains the following changes:
  - help message is reformatted to 80 characters (in commit
    9c203791a5)
  - typo fix (in commit ab5f526a21)
2020-10-20 22:40:39 +01:00
Serghei Iakovlev c93f3efe1f Restructuring Configure and Build jobs on GitHub Actions
This is a planned, intermediate change that prepares the following
things:

- Preparing to use different generators (Xcode, NMake, Ninja)
- Preparing to use rebuild and test documentation. This required
  renaming some steps
- Preparing to build libs
- Preparing to use Autotools
- Preparing to make a full migration of CMake builds from Travis CI

Notable improvements include the unification of the Configure job
(now it is Fast Configure) for all platforms
2020-10-20 15:18:33 +03:00
Serghei Iakovlev 8bfac019e5 Remove rst2man output redirection as it doesn't work on Windows
There is no need for redirect output with > (which doesn't work on
Windows) as this is how rst2man works:

  rst2man [options] [<source> [<destination>]]

For more see: https://github.com/skvadrik/re2c/issues/325
2020-10-20 09:34:51 +03:00
Serghei Iakovlev 0bb8e8711a Rephrase error messages for RE2C_REBUILD_DOCS=ON
This aims to provide a bit more clear error messages on regenerate
manpage stage as well as documentation.
2020-10-20 09:34:51 +03:00
Serghei Iakovlev eb0281382b Check for man and sed on Windows when RE2C_REBUILD_DOCS is ON
Windows does not have a native 'man' and 'sed' commands.
Therefore, we are looking for the Cygwin versions of 'man' and 'sed'.

For more see: https://github.com/skvadrik/re2c/issues/325
2020-10-20 09:34:51 +03:00
Serghei Iakovlev 9c203791a5 Add the ability to generate manpage and documentation for BSD systems
- Stripping headers may not work as expected, as man output differs
  on different systems. This should work now.
- Simplified output parsing procedure by replacing the regular
  expression by TERM=dumb.
- Stripping escape sequences.
- Added documentation about the intentions of this script.

For more see: https://github.com/skvadrik/re2c/issues/325
2020-10-20 09:34:51 +03:00
Serghei Iakovlev 41fc158928 Add contributing guidelines
Added notes regarding bootstrap regeneration
2020-10-19 10:22:53 +03:00
Serghei Iakovlev 7a5892fd91 Drop 'fatal' and 'Msg::fatal' in favor of 'error' and 'Msg::error'
This is aimed to reduce assumptions, workarounds and potential
misunderstandings due to not a completely obvious behavior of
'fatal' function.

For more see discussion on https://github.com/skvadrik/re2c/pull/320
2020-10-17 16:07:49 +03:00
Ulya Trofimovich 26f12d233b Merge pull request #322 from skvadrik/cmake-mkdir
Create output directories for CMake builds with RE2C_REBUILD_LEXERS=yes.
2020-10-17 11:35:16 +01:00
Ulya Trofimovich 787bfcd4fe Create output directories for CMake builds with RE2C_REBUILD_LEXERS=yes.
Fixes the following build scenario:

    $ mkdir stage1 && cd stage1
    $ cmake .. && make
    $ cd .. && mkdir stage2 && cd stage2
    $ cmake .. \
        -DRE2C_REBUILD_LEXERS=yes \
        -DRE2C_FOR_BUILD=$(pwd)/../stage1/re2c && make
2020-10-17 10:50:30 +01:00
Serghei Iakovlev ceb557ecbf Merge pull request #321 from sergeyklay/fix/asan-ubsan-linker-flags
Fixed linker flags for Asan and Ubsan profiles.
2020-10-16 19:49:13 +03:00
Serghei Iakovlev 4d69dd719a Don't add CMAKE_STATIC_LINKER_FLAGS flags to Asan/Ubsan builds
This is a fix for linker flags that were mistakenly added after
discussion at https://github.com/skvadrik/re2c/pull/318.

Although STATIC_LINKER is technically a program for "getting one library
from a bundle of something", it works *completely* differently than
EXE_LINKER and SHARED_LINKER.
2020-10-16 18:46:07 +03:00
Serghei Iakovlev a904ff8855 Merge pull request #319 from sergeyklay/install-re2c
Add minimal install test on GitHub Actions
2020-10-14 10:38:38 +03:00
Serghei Iakovlev 28b4501a3d Add minimal install test on GitHub Actions 2020-10-14 09:50:15 +03:00
Serghei Iakovlev ca1619885c Merge pull request #318 from sergeyklay/custom-build-types-support
Added Asan and Ubsan CMake profiles
2020-10-12 19:43:13 +03:00
Serghei Iakovlev 61dd522509 Use Asan and Ubsan CMake's build types in build scripts 2020-10-12 16:29:02 +03:00
Serghei Iakovlev 94032e3026 Added Asan and Ubsan CMake profiles 2020-10-12 10:35:08 +03:00
Ulya Trofimovich abe84e832a Merge pull request #317 from sergeyklay/github-actions-improvements
GitHub actions improvements
2020-10-10 12:24:21 +01:00
Serghei Iakovlev c90189f9e2 Correct linker's and compiler's flags usage 2020-10-10 13:16:16 +03:00
Serghei Iakovlev af4c59de7f Amended build matrix on GitHub Actions 2020-10-09 19:42:18 +03:00
Serghei Iakovlev ba6c96620c Replace deprecated set-env and add-path commands
See: https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
2020-10-09 11:57:02 +03:00
Ulya Trofimovich 8e56ce38af Merge pull request #316 from sergeyklay/compiler-flags
Setting up build type and debug compiler flags
2020-10-08 22:46:48 +01:00
Serghei Iakovlev 461ce54d13 Allow empty build type
For more see: https://github.com/skvadrik/re2c/pull/316
2020-10-08 12:07:19 +03:00
Serghei Iakovlev 3c7694f6c4 Added verbose output about the flags used 2020-10-07 13:31:01 +03:00
Serghei Iakovlev 22014a1380 Don't keep ALLOWABLE_BUILD_TYPES variable in global scope 2020-10-07 11:51:33 +03:00
Serghei Iakovlev d239978d7a Remove redundant build type check 2020-10-07 10:21:55 +03:00
Serghei Iakovlev 2898e41520 Use Release build type by default 2020-10-07 10:14:29 +03:00
Serghei Iakovlev 234351e16b Merge Re2cTryCXXFlag.cmake and Re2cCompilerFlags.cmake 2020-10-07 10:13:47 +03:00
Serghei Iakovlev 1b049fa8a8 Rename CMake lists 2020-10-07 10:11:29 +03:00
Serghei Iakovlev eaf19f948a Setting up build type and debug compiler flags 2020-10-06 10:14:34 +03:00
Ulya Trofimovich c23ed638c9 Merge pull request #315 from sergeyklay/build-type
Add Release build type to the build matrix
2020-10-05 13:55:41 +01:00
Serghei Iakovlev c4547fd71b Add Release build type to the build matrix 2020-10-05 12:09:18 +03:00
Ulya Trofimovich e0483119ef GitHub Actions CI: use common steps with a parameterized "run" script for different platforms. 2020-10-04 23:10:22 +01:00
Ulya Trofimovich 5d8f52bfd5 Merge pull request #314 from zenwerk/master
fix typo
2020-10-03 22:04:59 +01:00
zenwerk ab5f526a21 fix typo 2020-10-04 04:57:22 +09:00
Ulya Trofimovich 9293f2c617 Merge pull request #312 from sergeyklay/fix/find-bison
Cleaned up CMakeLists.txt to use platform independent bison search
2020-10-02 11:36:06 +01:00
Serghei Iakovlev 9ce9bf3fa5 Cleaned up CMakeLists.txt to use platform independent bison search
After discussion in
https://github.com/skvadrik/re2c/pull/311#discussion_r498687041,
I decided to double-check this approach again and made sure that it
actually works.
2020-10-02 13:00:49 +03:00
Ulya Trofimovich fdebdff641 Merge pull request #311 from sergeyklay/windows-support
Add Windows support for GitHub Actions
2020-10-02 10:35:06 +01:00
Serghei Iakovlev b93855e274 Minor CMakeLists.txt cleanup, improved bison search 2020-10-02 12:19:35 +03:00
Serghei Iakovlev a1a97dc2bb Add Windows support for GitHub Actions 2020-10-02 09:27:57 +03:00
Serghei Iakovlev a4ca8b48ff Change find_package to find_program for bison
We do not use the functionality provided by FindBISON e.g. BISON_TARGET and
so on.  All we need below is BISON_EXECUTABLE.  Thus, I replaced find_package
by find_program and set BISON_EXECUTABLE explicitly.  This is also fixes
searching executables on Windows systems.
2020-10-02 09:17:24 +03:00
Ulya Trofimovich 36248bb46a Merge pull request #310 from sergeyklay/macos-support
Add macOS support for GitHub Actions
2020-10-01 22:43:54 +01:00
Serghei Iakovlev 79b1093c65 Add macOS support for GitHub Actions 2020-10-01 22:15:11 +03:00
Ulya Trofimovich 78e2cf1471 Merge pull request #309 from sergeyklay/github-actions-support
Initial support of CI using GitHub Actions
2020-09-28 13:57:07 +01:00
Serghei Iakovlev 95d6b283cd Initial support of CI using GitHub Actions 2020-09-28 09:46:30 +03:00
Ulya Trofimovich 92c68aa08b Update documentation for end of input handling. 2020-09-25 07:42:02 +01:00
Ulya Trofimovich f3deaba0a3 Drop useless configuration in the tests.
The bounds check is generated anyway if EOF rule is used. Configuration
`re2c:yyfill:check = 1;` is redundant.
2020-09-21 08:07:13 +01:00
Ulya Trofimovich 520e5cd433 Disallow using -f, --storable state option if YYFILL is disabled.
-f, --storable-state option should not be used if YYFILL is disabled,
because without YYFILL the interrupt points do not necessarily
correspond to storable state labels (with generic API interrupts can
happen on any API invocation). This may cause subtle bugs when the
lexer is resumed from the wrong program point.
2020-09-17 23:45:03 +01:00
Ulya Trofimovich 6f328bf1fe Rename Go tests, add a script to run them. 2020-09-16 23:56:26 +01:00
Ulya Trofimovich 09b21d38c6 Use a better way to disable YYFILL but keep EOF check in the tests.
Instead of defining YYFILL to always return failure, disable it entirely
with `re2c:yyfill:enable = 0;`, but keep the check with
`re2c:yyfill:check = 1;`. This way re2c does not generate dead code that
invokes YYFILL and always fails.
2020-09-16 23:55:22 +01:00
Ulya Trofimovich f3bb438c27 Use ordinary DFA state for EOF rule instead of a special "yyeof" label. 2020-09-16 07:49:30 +01:00
Ulya Trofimovich a50f2ab452 A few clarifying comments. 2020-09-14 22:49:52 +01:00
Ulya Trofimovich 277f0295fc Fix EOF rule in cases when default rule * is not specified.
Previously EOF rule was added only at the code generation level: if was
neither present as an NFA state, nor in any of the final DFA states.
This doesn't work in case there is a nullable loop and the default rule
is not specified, because the initial state gets merged with other DFA
states, which shouldn't match EOF rule. As a result, EOF rule never
matched.

The fix is to add EOF rule on the regexp level as a match-empty rule "".
2020-09-14 22:09:01 +01:00
Ulya Trofimovich 90e5a237bf Merge pull request #307 from s-yasu/fix-utf8-decode
Fix UTF-8 decode for 4bytes rune
2020-09-14 22:07:51 +01:00
Satoshi Yasushima 30130a7941 Fix UTF-8 decode for 4bytes rune 2020-09-15 00:51:04 +09:00
Satoshi Yasushima ca3a455468 Add test for UTF-8 literals 2020-09-15 00:51:02 +09:00
Ulya Trofimovich ee125dab03 Silence -Wmatch-empty-string on trivial obviously nullable cases. 2020-09-10 23:52:53 +01:00
Ulya Trofimovich 960f881636 Remove unused NFA state kind. 2020-09-10 22:50:47 +01:00
Ulya Trofimovich 42a3a485b1 A few minor corrections in the paper.
- Added "preprint" footnote with a reference to the SPE article.
- Corrected submitted\revised/accepted dates.
- Added DOI.
- Changed bibliography style.
- Updated link to Glenn Fowler's page "An interpretation of the POSIX
  regex standard". It is still accessible from the Wayback Machine, but
  the links are not stable. The new link is to a manually uploded copy
  of the page.
2020-09-06 09:31:13 +01:00
Ulya Trofimovich ec2d4b262c Merge pull request #304 from s-yasu/fix-cmake-command
Fix CMake command from cmake to ${CMAKE_COMMAND}
2020-09-04 21:43:35 +01:00
Satoshi Yasushima d2f05de5e7 Fix CMake command from cmake to ${CMAKE_COMMAND} 2020-09-05 01:15:44 +09:00
Ulya Trofimovich 0265a212fa Small tweak in the docs. 2020-08-27 08:11:19 +01:00
Ulya Trofimovich 010b98d3f5 Better handling of path to include subdirectory in the tests.
The problem with the path to include subdirectory is that the tests
can be run from different places relative to the source directory
(an out-of-tree build can be anywhere). Therefore instead of hardcoding
a few possible locations in the test itself, it is better to use a path
relative to @top_srcdir@ and compute it once for all tests.
2020-08-27 07:56:51 +01:00
Ulya Trofimovich ff4ffb0596 Fix example for in-tree builds.
This example uses include file unicode_categories.re and specifies
paths to include directory using -I option. Since the test can be
run both in in-tree and out-of-tree builds, different include paths
are needed to cover different cases.

In addition it is necessary to disable line directives, otherwise the
unstable path to the include file gets embedded in the output file.
2020-08-27 00:01:52 +01:00
Ulya Trofimovich 54a1946880 Include example of lexing Unicode identifiers in the docs. 2020-08-26 23:36:10 +01:00
Ulya Trofimovich 6c37434641 Add example of lexing Unicode identifiers.
The example uses include file unicode_categories.re. It is a partial
fix for #269 "Add examples of Unicode in the docs".
2020-08-26 07:38:04 +01:00
Ulya Trofimovich 01d6299532 Remove duplicate tests for POSIX capturing groups.
The tests are generated with a Bash script from a list of test cases
that contain a regexp and a string. Some test cases use the same regexp
multiple times with a different string. For the autogenerated tests the
string is not used, so such test cases result in identical tests.

This patch changes the script to check for duplicates. The original set
of test cases remains unchanged and can be run with another script:

    test/posix_captures/.run/__run.sh
2020-08-24 22:08:47 +01:00
Ulya Trofimovich ebf3f3e5f8 libre2c: check if the base tag is negative before shifting fixed tags. 2020-08-23 10:22:43 +01:00
Ulya Trofimovich 0c91e61989 Add documentation for --fixed-tags option. 2020-08-22 09:20:56 +01:00
Ulya Trofimovich 992134f6ff Add fixed-tag optimization for nested tags (part 2).
Many tests have been updated, because some of the variable tags have
been turned into fixed tags.

The following script was used to check that skeleton tests for the new
re2c run without errors on the data (.input and .keys) generated both by
the new re2c and by the old re2c.

  if [ $# -ne 3 ]; then
      echo "usage: $0 <testdir> <re2c_new> <re2c_old>"
      exit 1
  fi

  testdir="$1"
  re2c_new="$2"
  re2c_old="$3"

  for f in `find $testdir -name '*.re'`; do
    echo $f

    # extract options
    opts="$(head -n 2 $f \
        | grep -E -a '^.*INPUT.*$' $f \
        | sed -E 's/.*\$INPUT -o \$OUTPUT(.*)$/\1/')"

    # run skeleton test with new re2c
    $re2c_new --skeleton $opts $f -oa.c && gcc a.c -oa && ./a

    # run skeleton test with new re2c on the data generated by old re2c
    mv a.c b.c
    $re2c_old --skeleton $opts $f -oa.c && gcc b.c -o b && ./b

    # cleanup
    rm -f *.keys *.input a b
  done
2020-08-22 08:59:58 +01:00
Ulya Trofimovich 3783bb0335 Add tests for --fixed-tags option.
Some exisitng tests have been changed to explictly set option
`--fixed-tags toplevel` or `--fixed-tags none`. These tests would be
affected by flipping the default from `toplevel` to `all`, because some
of the variable tags would become fixed, making the whole test useless,
as it no longer tests what it is supposed to test.

For some tests "nofix" variants have been added. Currently the generated
code is the same as for the base variant, but this will change after
flipping the default from `toplevel` to `all`.
2020-08-22 08:59:58 +01:00
Ulya Trofimovich 47cecdc79a Add internal option --fixed-tags <none | all | toplevel>. 2020-08-22 08:59:58 +01:00
Ulya Trofimovich bda07a8cf4 Correctly set final tags that correspond to multiple capturing groups.
With POSIX capturing groups one tag may correspond to multiple capturing
parentheses, as in ((e)). Previously re2c generated assignment chains
like `yypmatch[i] = yypmatch[i+2] = ...` and treated the whole chain as
a single l-value. This doesn't work in cases that are more complex than
a simple assignment, for example with generic API when the shift
distance is nonzero (it is not possible to shift the whole chain of
assignments in one operation).

This patch fixes the broken cases when a tag expands to multiple tags by
setting the first tag (which may require multiple statements or checks),
and then assigning the remaining tags to the first tag.
2020-08-22 08:59:58 +01:00
Ulya Trofimovich 81705b8f13 Add fixed-tag optimization for nested tags (part 1).
When applying fixed tags optimization to tags that are enclosed in
alternative or repetition it is necessary to check if the base tag has a
no-match value (in that case fixed tag should also be set to no-match).
For tags in top-level concatenation the check is not needed, because
they always match.

This commit implements the optimization, but does not enable it yet
(that would require updatimg many test results and will be done in a
separate commit).

This is related to bug #281 "Apply fixed tags optimization more
aggressively".
2020-08-22 08:59:58 +01:00
Ulya Trofimovich 5e16ca05d3 Minor correction of a bug reference in CHANGELOG. 2020-08-22 08:22:58 +01:00
Ulya Trofimovich 23a3a1f532 Release 2.0.3. 2020-08-22 08:12:59 +01:00
Ulya Trofimovich 2b76a87d08 Update CHANGELOG for release 2.0.3. 2020-08-22 08:01:26 +01:00
Ulya Trofimovich 0b87ac7bd4 SIMPA article: final corrections before publication.
- Fixed final state number in the example from 8 to 10.
- Re-worded a few sentences.
2020-08-21 08:22:49 +01:00
Ulya Trofimovich c1b246a8e3 CMake: add an example of building re2c as a subproject. 2020-08-19 22:39:44 +01:00
Ulya Trofimovich e626849408 CMake: move build rules for docs out of conditional branch.
These rules are always needed (e.g. the file help.cc generated by these
commands is one of the source files that are required for the minimal
build). The rules were accidentally moved under conditional branch in
commit be688fdc6d, and were enabled only
if re2c is the root project. This caused a build error "Cannot find
source file" when trying to build re2c as a subproject:

  ├── other
  │   ├── build
  │   └── CMakeLists.txt
  └── re2c

With the following other/CMakeLists.txt:

  project(other)
  add_subdirectory(../re2c re2c-build)

This is a partial fix for #302 "Using CMake add_subdirectory fails".
2020-08-19 22:21:25 +01:00
Ulya Trofimovich 4c97baa591 Release 2.0.2. 2020-08-08 09:04:08 +01:00
Ulya Trofimovich b2e2d75308 Update CHANGELOG for release 2.0.2. 2020-08-08 08:59:44 +01:00
Ulya Trofimovich 8ff0df653e SIMPA article: add link to the reproducible capsule on Code Ocean. 2020-08-08 08:53:56 +01:00
Ulya Trofimovich 157bc8f356 Debug: output minus sign for negative tags with --dump-dfa-tree. 2020-07-31 23:20:40 +01:00
Ulya Trofimovich 77da086ec3 Package CMake files into release tarballs. 2020-07-30 22:08:50 +01:00
Ulya Trofimovich ec654f12cb Enable re2go building by default. 2020-07-30 09:39:26 +01:00
Ulya Trofimovich 0e5443b2d2 Address reviewers' remarks to the artcle for Software Impacts journal.
Added "Impacts" section and more references to projects that use re2c.
2020-07-30 07:28:20 +01:00
Ulya Trofimovich 2072fa1048 Release 2.0.1. 2020-07-29 18:34:16 +01:00
Ulya Trofimovich 9311e5295c Fix release script to update re2c version for CMake. 2020-07-29 18:32:29 +01:00
Ulya Trofimovich 66c8e21495 Add a short article about re2c for the Software Impacts journal. 2020-07-28 23:21:09 +01:00
Ulya Trofimovich a058ba18fc Release 2.0. 2020-07-20 19:25:21 +01:00
Ulya Trofimovich 1a8568e871 Updated CHANGELOG. 2020-07-20 18:55:00 +01:00
Ulya Trofimovich 6261543445 run_tests.sh: fix grep invocation and typo in variable name. 2020-07-20 09:08:00 +01:00
Ulya Trofimovich eb5c63dc7b Merge pull request #298 from trofi/master
run_tests.sh.in: add usage example
2020-07-20 01:17:17 +01:00
Sergei Trofimovich 8198c794ba run_tests.sh.in: add usage example
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2020-07-20 01:02:53 +01:00
Ulya Trofimovich 4da53fc99e Avoid ambiguity in the generated DFA names in the presence of include files.
If the definition of a re2c block comes from an include file, use the name of
the file as well as the block line to generate a unique DFA name. The block
line itself is insufficient as there may be two blocks on the same line in
different files.

This has caused an error in one of the skeleton tests.
2020-07-19 17:24:53 +01:00
Ulya Trofimovich 1f93425fbd Get rid of options in test filenames (part 8).
Rename Unicode tests. Rename is needed because Unicode tests are
clustered into groups of similar tests that have similar filenames,
and the previous rename left one tests of a grop having a short filename
without options, while the remaining tests have options in the filename.

Update test generator and script that runs Unicode tests.
2020-07-19 17:24:53 +01:00
Ulya Trofimovich b853513b47 Get rid of options in test filenames (part 7).
Update test generator for character classes.
2020-07-19 17:24:53 +01:00
Ulya Trofimovich c8fe2104dc Get rid of options in test filenames (part 6).
Rename POSIX submatch tests. Update generator.
2020-07-19 17:24:52 +01:00
Ulya Trofimovich aa0592d99f Replace many tiny tests for flex support with one bit test. 2020-07-19 17:24:52 +01:00
Ulya Trofimovich 1a8a0ce7ca Remove a few not-so-useful skeleton tests. 2020-07-19 17:24:52 +01:00
Ulya Trofimovich 0a55a58461 Rewrite layout tests.
This commit replaces many (~128) autogenerated layout tests with a few
hand-written tests. The autogenerated tests were not very useful as they
covered many similar trivial use cases, and only a few interesting ones.
2020-07-19 17:24:52 +01:00
Ulya Trofimovich 3d2fbb5238 Get rid of options in test filenames (part 5).
Update autogenerator for layout tests.
2020-07-19 17:24:52 +01:00
Ulya Trofimovich ebfefb671f Get rid of options in test filenames (part 4).
Update autogenerator for config tests, rename config tests.
2020-07-19 17:24:52 +01:00
Ulya Trofimovich 390e13b3ff Get rid of options in test filenames (part 3).
Update example filenames in docs and build files, regenerate manpages.
2020-07-19 17:24:52 +01:00
Ulya Trofimovich 277e2c8c8f Get rid of options in test filenames (part 2).
This commit renames test files and patches filename strings embedded in
line directives, warnings, error messages, etc. in the generated output.

When possible, all options have been dropped from the filename. In cases
when this would cause collision due to multiple different tests being
renamed to the same file, only the first test has a filename without
options, and the remaining tests have filenames with options where all
special characters have been replaced with underscores.

Conversion has been done automatically with the following Bash script:

  #!/bin/bash

  for f in `find . -name '*.re'`; do
    stem="$(basename $f | sed -E -e 's/^([^.]+)\..*$/\1/')"
    ext="$(basename $f | grep -q -- '--lang(go)' && echo go || echo c)"
    x="${f%.re}.$ext"
    newf="$(dirname $f)/$stem.re"
    newx="$(dirname $f)/$stem.$ext"

    if [ "$f" == "$newf" ]; then
        continue
    elif [ -e "$newf" ]; then
        sfx="$(basename $f | sed -E -e 's/^([^.]+)[.](.*)[.]re$/\2/' -e 's/[(.+-]+/_/g' -e 's/[)]//g')"
        newf="$(dirname $f)/${stem}_$sfx.re"
        newx="$(dirname $f)/${stem}_$sfx.$ext"
    fi

    a="$(echo $(basename ${f%.re}) | sed -E -e 's/([()])/\\\1/g' -e 's/\./\\./g')"
    b="$(basename ${newf%.re})"
    perl -p -e 's/'"$a"'/'"$b"'/g' "$f" > "$newf"
    perl -p -e 's/'"$a"'/'"$b"'/g' "$x" > "$newx"
    rm "$f" "$x"
  done
2020-07-19 17:24:52 +01:00
Ulya Trofimovich 303ef47837 Get rid of options in test filenames (part 1).
This commit adds a comment with options to the beginning of each .re file.
Because of the added line all test results had to be updated (line numbers
in line directives, error messages, warnings, etc. have increased by one).

The testing script run_test.sh has been changed to use options in the
comments rather than options in the filenames.

Conversion has been done almost automatically (except for a few rare tricky
cases) with the following horrible Bash script:

  #!/bin/bash

  for f in `find . -name '*.re'`; do
    switches=`basename "$f" | sed \
        -e 's/^[^.]*\.re$//g' \
        -e 's/^[^.]*\.\(.*\)\.re$/\1/g' \
        -e 's,[+],/,g' \
        -e 's/^\([^-]\)/-\1/' \
        -e 's/--\([^ (-]*\)/ --\1/g' \
        -e 's/(\([^)]*\))/ \1/g' \
    `
    ext=`basename "$f" | grep -q -- '--lang(go)' && echo go || echo c`
    x="${f%.re}.$ext"
    ff="$f.mod"
    xx="$x.mod"
    linedirs=`egrep -q -- '(#|//)line' "$x" && echo 1 || echo 0`
    dot=`echo "$switches" | fgrep -q -- ' --emit-dot' && echo 1 || echo 0`
    skel=`echo "$switches" | fgrep -q -- ' --skeleton' && echo 1 || echo 0`
    if [ $ext == c ]; then
        l='// re2c $INPUT -o $OUTPUT '"$switches"
    else
        switches=`echo "$switches" | sed 's/ --lang go//'`
        l='//go:generate re2go $INPUT -o $OUTPUT '"$switches"
    fi
    nocomment=0
    if [ "$(tail -n 1 $x | fgrep -q 'error: ' ; echo $?)" -eq 0 ]; then
        nocomment=1
    elif [ $dot -eq 1 ]; then
        nocomment=1
    elif [ $skel -eq 1 ]; then
        nocomment=1
    fi

    echo "$l" > "$ff"
    cat "$f" >> "$ff"
    if [ $linedirs -eq 0 ]; then
        head -n 1 "$x" > "$xx"
        if [ $nocomment -eq 0 ]; then echo "$l" >> "$xx"; fi
        tail -n +2 "$x" >> "$xx"
    else
        head -n  2 "$x" > "$x.head"
        tail -n +3 "$x" > "$x.tail"
        if [ $nocomment -eq 0 ]; then echo "$l" >> "$x.head"; fi
        if [ $ext == c ]; then
            e='s/^([ \t]*#line )([0-9]+)(.*\.re"|.*\.c")$/($1).($2+1).($3)/eg'
        else
            e='s/^(\/\/line ".*".)([0-9]+)$/($1).($2+1)/eg'
        fi
        perl -p -i -e "$e" "$x.tail"
        cat "$x.head" "$x.tail" > "$xx"
        rm "$x.head" "$x.tail"
    fi

    a="$(basename $f | sed -E -e 's/([()])/\\\1/g' -e 's/\./\\./g')"
    perl -p -i -e 's/^(.*'"$a"'[:(])([0-9]+)(.*)$/($1).($2+1).($3)/eg' "$xx"
    perl -p -i -e 's/^(.*shadowed by rule at line )([0-9]+)(.*)$/($1).($2+1).($3)/eg' "$xx"
    perl -p -i -e 's/^(.* already defined at line )([0-9]+)(.*)$/($1).($2+1).($3)/eg' "$xx"
    if [ $skel -eq 1 ]; then
        perl -p -i -e 's/^(.*[_.]line)([0-9]+)(.*)$/($1).($2+1).($3)/eg' "$xx"
    fi
  done

  find . -name '*.re' -o -name '*.c' -o -name '*.go' | xargs rm
  for f in `find . -name '*.mod'` ; do mv "$f" "${f%.mod}" ; done
2020-07-19 17:24:51 +01:00
Ulya Trofimovich 316c02d06f run_tests.sh: clean up auxiliary test files. 2020-07-14 08:09:35 +01:00
Ulya Trofimovich 6dfd2969d3 Makefile.am: remove nonexistent header from the list. 2020-07-14 08:02:25 +01:00
Ulya Trofimovich 14363b90c6 Updated README.md. 2020-07-13 22:56:28 +01:00
Ulya Trofimovich 078d2fded1 Update paths in a testing script. 2020-07-12 18:35:54 +01:00
Ulya Trofimovich eb48666e20 Update .travis.yml to make a second build that rebuilds lexers. 2020-07-12 10:54:02 +01:00
Ulya Trofimovich 967540566b Makefile.am, CMake: simplify bootstrap process.
Re2c is a self-hosting lexer generator, therefore it needs re2c in order
to rebuild itself. It bootstraps using precompiled files in the bootstrap
subdirectory. Precompiled files can be used as long as the .re files are
not changed, otherwise lexers must be regenerated. Previosuly the build
system tried to autodetect whether to regenerate or to copy bootstrap
files by checking if the re2c executable exists in the build directory.

However, for the build system it means that dependency graph is changed
on every build, because bootstrap commands and regenerate commands have
different dependencies: bootstrap commands depend on the bootstrap
files, and regenerate commands depend on the .re files. It is not
possible to choose the commands statically, because the check for re2c
executable should run on every build rather than once at configure time.
CMake used a workaround and set both bootstrap and .re files as
dependencies for both commands, which caused weird rebuilds on Travis CI
(when the same lexer was regenerated multiple times during one build).
Automake used a different workaround (a pattern rule that didn't have
the dependency on bootstrap files at all).

This commit disables the checking mechanism and requires passing an
explicit configure parameter and a path to the re2c executable in order
to regenerate lexers. Otherwise, by default lexers are copied from
bootstrap files.

CMake:       cmake ...  -DRE2C_REBUILD_LEXERS=on -DRE2C_FOR_BUILD=<path>
Makefile.am: configure ... --enable-lexers RE2C_FOR_BUILD=<path>
2020-07-12 10:54:02 +01:00
Ulya Trofimovich f025279f98 CMake: require version 3.12 or higher.
CMakeLists.txt uses features such as HOMEPAGE_URL parameter in project()
command and add_compile_definitions() command that were introduced in
CMake version 3.12.

This fixes bug #297 "configure error on ubuntu 18.04 / cmake 3.10".
2020-07-12 08:44:24 +01:00
Ulya Trofimovich 4c0391e2cf Update docs (reorder and rewrite a few sections). 2020-07-10 22:50:45 +01:00
Ulya Trofimovich f811f03006 Use correct options for the first normal block in reuse mode.
Normal blocks should use global options that are accumulated over all
non-reuse blocks, and use blocks should use options of the preceding
rules block, plus the options added by the use block itself. Before
this commit re2c failed to set up global options correctly, and as a
result the first normal block had incorrect options if it was preceded
by some reuse blocks.
2020-07-07 23:29:54 +01:00
Ulya Trofimovich 2a9c122e67 Allow to use normal (non-conditional) blocks in -c mode.
This fixes issue #296 "Conditions required for all lexers when using
'-c' option" reported by Joshua Inscoe.
2020-07-07 23:28:26 +01:00
Ulya Trofimovich a1ebb2e111 Generate condition switch in every re2c block.
Previously in condition mode re2c generated condition switch only for
the first re2c block in the file. This makes it impossible to have
multiple re2c blocks with conditions. The change in this commit doesn't
break backwards compatibility, because the case that was previously
supported (with one lexer per file) works in the same way as before,
and the previously unsupported case (with multiple lexers) now works.

This fixes bug #295 "Condition switch generated for only one lexer per
file" reported by Joshua Inscoe.
2020-07-06 07:58:51 +01:00
Ulya Trofimovich 4a91b65917 Add examples of include files for C and Go backends. 2020-07-05 19:03:24 +01:00
Ulya Trofimovich fc0f73e31c Update tests for reuse mode (move common configurations to rules blocks). 2020-07-05 12:03:06 +01:00
Ulya Trofimovich b7e62a1341 Do not reset API-related configurations in each use:re2c block.
This change breaks backwards compatibility for some (rare) use cases.

For historical reasons re2c reset all API-related configurations to
default values in each `/*!use:re2c ... */` block. This behaviour is
illogical and inconvenient: the whole purpose of reuse mode is to share
configurations, definitions and rules between blocks, and resetting
selected configurations means that they have to be redefined in each
reuse block. This has caused confusion (see bug #291 "Defines in rules
block are not propagated to use blocks" reported by Joshua Inscoe).

The odd behavior was kept for backwards compatibility. It goes back to
the versions of re2c and was probably introduced accidentally or by
mistake. It is unlikely that many users rely on the old behavior: if
they need user-defined configurations in some of the blocks and default
configurations in other blocks, it is more likely that they would
explicitly reset them to defaults rather than rely on undocumented re2c
behavior.

The change affects the following configurations:

    re2c:define:YYGETCONDITION
    re2c:define:YYSETCONDITION
    re2c:define:YYFILL
    re2c:define:YYGETSTATE
    re2c:define:YYSETSTATE
    re2c:define:YYBACKUP
    re2c:define:YYBACKUPCTX
    re2c:define:YYCONDTYPE
    re2c:define:YYCTXMARKER
    re2c:define:YYCTYPE
    re2c:define:YYCURSOR
    re2c:define:YYDEBUG
    re2c:define:YYLESSTNAN
    re2c:define:YYLIMIT
    re2c:define:YYMARKER
    re2c:define:YYPEEK
    re2c:define:YYRESTORE
    re2c:define:YYRESTORECTX
    re2c:define:YYRESTORETAG
    re2c:define:YYSTAGN
    re2c:define:YYSTAGP
    re2c:define:YYMTAGN
    re2c:define:YYMTAGP
    re2c:define:YYSHIFT
    re2c:define:YYSHIFTSTAG
    re2c:define:YYSHIFTMTAG
    re2c:define:YYSKIP
    re2c:label:yyFillLabel
    re2c:label:yyNext
    re2c:variable:yyaccept
    re2c:variable:yybm
    re2c:variable:yych
    re2c:variable:yyctable
    re2c:variable:yytarget
2020-07-05 10:11:43 +01:00
Ulya Trofimovich 09ef30b634 Don't loose "diverge" bit when setting options with custom handlers.
Whenever an option is set or unset by the user, re2c needs to remember
that user-defined options have been updated and have diverged from the
real options. Any following attempt to read options must trigger
synchronization of user-defined and real options. Previously this was
handled correctly for all options except those with custom handlers.
2020-07-05 09:59:33 +01:00
Ulya Trofimovich 6b477d25a2 Merge pull request #293 from trofi/master
.travis.yml: split build commands into individual entries
2020-07-04 20:46:17 +01:00
Sergei Trofimovich 3daf44f304 .travis.yml: split build commands into individual entries
This should allow travis CI measure individual times on each step

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2020-07-04 19:51:07 +01:00
Ulya Trofimovich 374c4a7e32 Add header examples for C and Go to the manpage. 2020-07-04 19:20:50 +01:00
Ulya Trofimovich 6a6c7e092a CMake, Makefile.am: add generation scripts to the dependencies of make docs. 2020-07-04 18:25:35 +01:00
Ulya Trofimovich baa843cfe2 Merge pull request #292 from ryandesign/oldcompilers
Fix for old compilers like gcc 4.2 and clang 3.4
2020-07-04 18:13:46 +01:00
Ryan Schmidt fe285f03d5 Fix for old compilers like gcc 4.2 and clang 3.4
Fixes the build for old compilers that can't deduce const overload for
rend.

Similar to previous problem reported in #198.
2020-07-04 08:36:54 -05:00
Ulya Trofimovich e2f29c1691 Update scripts that run examples to handle autogenerated headers.
The run_tests.sh script generates output for all examples and appends
the generated header at the end of the output file (to make it easier to
diff actual and expected output). Script that run examples from
autogenerated output need to cut off the appended header, otherwise the
example won't compile/run.
2020-07-04 10:39:45 +01:00
Ulya Trofimovich dc0df494c6 Remove re2c:flags:output and make re2c:flags:type-header relative to the output directory.
Before this patch the filename specified in `re2c:flags:t`,
`re2c:flags:type-header` configuration was relative to the directory
of the source file. It is inconvenient for out-of-tree builds, when the
output is generated in a directory different from the source directory
(which may be read-only). Therefore this patch makes the filename in
configuration relative to the directory of the output file.

As for the `re2c:flags:o`, `re2c:flags:output` configuration, it is
removed altogether. Making it relative to the source directory has the
same problems as with the header file, and making it absolute or
relative to the build directory (where re2c is run) is also bad,
because build-related information will have to be hard-coded in the
source file. Given that this is a relatively new configuraion and it
hasn't been documented in any released version of re2c, it is better to
delete it.

The change does not affect `-t`, `--type-header` and `-o`, `--output`
command-line options.
2020-07-04 09:54:54 +01:00
Ulya Trofimovich 0b0622ce54 Add examples of header file generation for C and Go. 2020-07-04 08:34:16 +01:00
Ulya Trofimovich 33417a1119 Paper: address editor remarks (add affiliation and cite figures). 2020-07-03 23:15:40 +01:00
Ulya Trofimovich 56a5dadecf Lexer: make header name relative to the lexer source file.
This fixes build error for in-tree builds wit hlexer regeneration,
broken after recent commit 5d130e89cc
that made filenames in configurations relative to the directory of the
source file.
2020-07-03 23:12:17 +01:00
Ulya Trofimovich 3b5a4ac4b6 run_tests.sh: do not copy each test into temporary subdirectory before running.
Previously we did this to avoid tracking all the files generated by a
test run (optional header files, skeleton artifacts, etc.) However, this
approach has problems with tests that generate header in a nested
subdirectory: directory structure needs to exist (otherwise re2c won't
be able to open the header file), but re-creating it in a temporary
subdirectory is problematic (`find` collides with other threads running
in parallel, creating and removing directories).

Instead of using a sandbox, track all files generated by a test (that
turns out to be not so difficult with shell globs).

This patch adds a requirement that all tests that use header must
specify it explicitly in the test options (in filename) using the long
option --type-header. Also, this patch allows using plus sign in the
argument to --type-header option to substitute for slash (that cannot be
used in filenames). This allows one to specify headers in nested
subdirectories.
2020-07-03 22:22:09 +01:00
Ulya Trofimovich 5d130e89cc Make filenames in configurations relative to the source file directory.
Prepend source file directory to these filenames when parsing
configurations and updating the corresponding options.

The affected configurations are:
    `re2c:flags:o`, `re2c:flags:output`
    `re2c:flags:t`, `re2c:flags:type-header`

The reason for this change is to make the contents of the source files
independent of the subdirectory where they are located relative to the
build directory where re2c is run. Otherwise it is necessary to hardcode
the relative path in the configuration and change it every time when
either the source file is moved to another subdirectory, or the build
directory is changed.

This change breaks backwards compatibility. However, the configurations
have been added not very long ago (in re2c-1.2) and not documented yet,
so it is likely that not many users will be affected. The corresponding
command-line options `-o`, `--output` and `-t`, `--type-header` remain
unchanged.
2020-07-03 22:20:46 +01:00
Ulya Trofimovich 6704dcef5a Extend fixed tags optimization for the case of fixed-counter repetition.
Previosly RE like `@t "xxx"` that use manual repetition were optimized,
but RE like `@t "x"{3}` that use fixed repetition counters were not,
even though they are unrolled to the same RE.
2020-06-30 23:14:16 +01:00
Ulya Trofimovich 7af9d3383a Make go generate comments in Go examples less cryptic. 2020-06-30 08:07:40 +01:00
Ulya Trofimovich d0c3b256e3 Make docs more Go-friendly. Add conditions example. 2020-06-30 08:07:40 +01:00
Ulya Trofimovich 27f7b3506c Add introductory example to the manpages. 2020-06-30 08:07:40 +01:00
Ulya Trofimovich b4f65a723e Use pregenerated output for running gotest on Go examples. 2020-06-29 22:14:20 +01:00
Ulya Trofimovich 77900c2805 Update introductory examples for C and Go. 2020-06-29 22:14:20 +01:00
Ulya Trofimovich be688fdc6d Add manpage for re2go (generated from the same source, but with Go examples).
Go manpage should be generated and installed only if the Go backend is
enabled. Both CMake and Autotools build systems take care of that.
2020-06-28 23:01:41 +01:00
Ulya Trofimovich 37d8966037 Rename C examples: add --lang(c) option to the filenames.
This is needed to unify C and Go example names (to be used in scripts).
2020-06-28 22:58:39 +01:00
Ulya Trofimovich accc5a2046 Get rid of accidental option duplication in a test filename. 2020-06-28 16:47:38 +01:00
Ulya Trofimovich 1ab43f38b1 Fix the way help message is generated, update its bootstrap file.
Changes:
- Use MANPAGER instead of PAGER (no significant difference).
- Set MANWIDTH=100 and to get deterministic line width.
- Tweak genhelp.sh as it was cutting off too many lines in the generated
  output (presumably something has changed in the way man works).
2020-06-28 10:54:21 +01:00
Ulya Trofimovich fa36ff5589 Move C examples into subdirectory. Update paths in build files, tests and docs.
Changes in the generated test output are trivial (file paths in line
directives and warnings).
2020-06-28 10:37:31 +01:00
Ulya Trofimovich 7432c2af07 Add examples for the Go backend. 2020-06-28 10:21:23 +01:00
Ulya Trofimovich 5033918f1e Avoid duplicate EOF labels with conditions.
Include condition name in the name of the label.
The issue was reported Joshua Inscoe.
2020-06-27 21:25:08 +01:00
Ulya Trofimovich 8d854c87f3 Update docs for user interface and configurations.
Changes:

- Added new generic API primitives:
    YYSHIFT
    YYSHIFTSTAG
    YYSHIFTMTAG

- Added new configurations:
    re2c:api:style
    re2c:api:sigil

- Rewrote the "user interface" section.

- Reordered configuraions and API primitives (grouped them by their
  meaning instead of sorting alphabetically).
2020-06-26 22:25:05 +01:00
Ulya Trofimovich 25de893b6a CMake: fix dependencies of docs target and clean up its build rules. 2020-06-23 22:50:57 +01:00
Ulya Trofimovich ae668ea69c Document --case-ranges option and re2c:flags:case-ranges configuration. 2020-06-23 22:49:49 +01:00
Ulya Trofimovich bb0d1973bf Paper: address reviewer's comments on 2nd review.
Changed IRE notation from expressions with operators like (i,J,e_1|e_2)
to more explicit Alt(i,J,e_1,e_2) to avoid confusion around the fact that
e_1|e_2 is neither an IRE nor a RE, but only a part of syntactic form.
2020-06-21 18:36:13 +01:00
Ulya Trofimovich cb11abb3d4 Add code generation option --case-ranges.
The new option defaults to false. Also, add a corresponding boolean
configuration `re2c:flags:case-ranges = 0;`.

The new option allows to generate compact cases of the form
`case low ... high:` in switch statements. This is not standard C/C++
syntax, but some compilers (GCC, Clang, Tcc) support it.

This implements #290 "use switch range" suggested by algorithm314.
2020-06-19 22:39:34 +01:00
Ulya Trofimovich dcdab01320 Small clarifying comment to the argsubst function. 2020-06-19 00:08:33 +01:00
Ulya Trofimovich cb1eae4db9 Merge pull request #289 from trofi/master
autogen.sh: always attempt to create m4/ directory
2020-06-19 00:08:18 +01:00
Sergei Trofimovich 29932c4c7e autogen.sh: always attempt to create m4/ directory
On a fresh checkout `autogen.sh` complains about missing `m4`:

```
$ ./autogen.sh
aclocal-1.16: warning: couldn't open directory 'm4': No such file or directory
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
...
```

The change always attempts to create the directory.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2020-06-19 00:06:37 +01:00
Ulya Trofimovich 87eef41c1a Fix GCC-10 warning -Wreturn-local-addr.
Previously the function was not erroneous, because only the head of the
newly constructed list was in a local stack variable, and the rest
consisted of reordered elements from the input list. The offending
pointer was initially set to the head of the list (local addr), and
then advanced to subsequent elements. The case when it was not advanced
and still pointed at the local variable was handled in a special way by
returning NULL.

This patch slightly rewrites topsort to use the output parameter
instead of a local variable as the head of the new topsorted list.
2020-06-17 23:09:01 +01:00
Ulya Trofimovich 2293b32c85 Fix Clang warning -Wunused-template. 2020-06-17 22:15:45 +01:00
Ulya Trofimovich dc0e4869f0 Don't bother resetting selected options for the DOT backend.
These options are unused anyway, and the list is not properly updated.
Restructure code to avoid Clang warning -Wimplicit-fallthrough.
2020-06-17 22:08:27 +01:00
Ulya Trofimovich 68139306fd CMake: fix misspelled name in macro definition.
The typo in the macro name resulted in not using re2 library in libre2c
benchmark, even though it was found by CMake. The error was revealed by
Clang warning -Wunused-const-variable.
2020-06-17 08:08:21 +01:00
Ulya Trofimovich 18f80c62b7 Fix some of Clang warnings -Wunused-macro. 2020-06-17 07:41:17 +01:00
Ulya Trofimovich 4230f5f5a1 Fix Clang warning -Wunused-function. 2020-06-17 07:36:32 +01:00
Ulya Trofimovich bbd7fa2068 Fix Clang warning -Wshadow. 2020-06-17 07:30:18 +01:00
Ulya Trofimovich 4c12c4f121 Remove accidentally committed files. 2020-06-17 07:26:46 +01:00
Ulya Trofimovich 0cb1caa3e5 Fix Clang warning -Wunused-value. 2020-06-17 07:19:42 +01:00
Ulya Trofimovich a3c743556d Fix Clang warning -Wmismatched-tags. 2020-06-17 07:15:57 +01:00
Ulya Trofimovich 00623ce0b1 CMake: get rid of redundant local variables. 2020-06-16 22:26:58 +01:00
Ulya Trofimovich fa53e63b12 Move build scripts to subdirectory. 2020-06-16 22:17:59 +01:00
Ulya Trofimovich fd3bdc2e2f CMake: avoid generating ver_to_vernum.cc multiple times.
Build it into a separate CMake object library in order to have one
target that is a dependency of all other targets.
2020-06-16 21:54:37 +01:00
Ulya Trofimovich 8e1913685b CMake: build autogenerated sources once and before everything else.
This patch fixes builds whn both options -DRE2C_BUILD_RE2GO and
-DRE2C_REBUILD_DOCS are set (previously in that case help.cc would be
generated twice, which caused a race and resulted in garbage output).

The desired behaviour is analogous of Automake BUILT_SOURCES. Buld all
autogenerated sources into an object library, and make that library a
dependency of the main target. Note that custom target that depends on
the autogenerated sources can't be used instead (although it may seem
the right solution at first), because somehow it triggers building of
its dependencies multiple, which ruins parallel builds.
2020-06-16 08:06:41 +01:00
Ulya Trofimovich bb525fec00 Build a standalone executable re2go (same as re2c --lang go).
For CMake this is turned on with `-DRE2C_BUILD_RE2GO`.
For Autotools this is enables with `--enable-golang`.
2020-06-15 22:15:50 +01:00
Ulya Trofimovich 0b44c9991b Rename decorate->api:style, placeholder->api:sigil.
These configurations haven't been released or documanted yet, so it is
safe to rename them.
2020-06-14 10:39:09 +01:00
Ulya Trofimovich e87f231052 Add a script to run Go test programs. 2020-06-12 22:42:56 +01:00
Ulya Trofimovich 67bba2c099 Fix skeleton to handle EOF rule.
Previously configuration `re2c:eof` was reset to default in skeleton
mode, resulting in a re2c error "EOF rule is used, but `re2c:eof` is
not set". Since re2c errors are not failures in skeleton tests (some
tests do actually test re2c errors), such cases increased the number
of "expected re2c errors", but did not show up as failed tests.

This patch increases the number of tests that run successfully with
--skeleton by some 28 test cases.
2020-06-12 22:21:26 +01:00
Ulya Trofimovich 4a94769fd5 Report the number of ran tests and soft/hard failures in run_tests.sh.
Soft failures are needed for skeleton tests: in some cases re2c fails to
set correct configurations and the test results in a re2c error, which
is not a hard error (because some tests do test re2c errors).
2020-06-12 18:21:59 +01:00
Ulya Trofimovich 5ce3368c4b Fix accidentally forgotten yyeofrule label prefixes to yyeof.
The generated code had `yyeofrule` labels, but jumps to `yyeof` labels,
so the program would not compile. This inconsistency was introduced in
commit 4253577f47.
2020-06-12 07:09:17 +01:00
Ulya Trofimovich 8d87a97de8 Don't generate space between API name and opening parenthesis.
Changes in the tests are numerous, but trivial (this can be verified
with changing `diff` to `diff -w` in run_tests.sh: given an option to
ingnore all space changes, diff finds no difference and all tests pass).
2020-06-11 23:52:44 +01:00
Ulya Trofimovich d769f57106 Simplify code generation of final tag operations. 2020-06-11 23:26:01 +01:00
Ulya Trofimovich d403262300 Add helper function for tag "copy" operation. 2020-06-11 22:56:44 +01:00
Ulya Trofimovich 64b7c1b4f7 Reuse the same helper function for all "shift" operations. 2020-06-11 22:56:44 +01:00
Ulya Trofimovich 0eb4da6728 Deduplicate code for "context restore" operation into a helper function. 2020-06-11 22:56:15 +01:00
Ulya Trofimovich b53cca5c11 Use a more elegant way to traverse reversed tag history. 2020-06-11 22:54:40 +01:00
Ulya Trofimovich 77078075d1 Deduplicate code for tag operations into helper functions. 2020-06-11 22:54:07 +01:00
Ulya Trofimovich 80a35ce79a Fix erroneous reference binding to null pointer.
Reported by ubsan:
    runtime error: reference binding to null pointer of type 'const struct Tag'

There was no actual crash, as the bound null value wasn't used.
2020-06-10 23:28:23 +01:00
Ulya Trofimovich 3c8cab9459 Add named placeholders in interpolated configuration strings.
Previously re2c allowed to use @@ or a custom string as a placeholder
for an argument in API primitives. With the addition of multi-argument
APIs like YYSHIFTSTAG and YYSHIFTMTAG this has become ambiguous. The
first attempt to resolve ambiguity was to use @@1, @@2, etc. This works,
but it is not perfect for two reasons. First, it is not clear how to
handle multi-digit suffixes: @@12 can be @1 followed by symbol 2, or it
can be @12 (but it is unlikely that re2c will ever have and API with 12
arguments, so it is most likely an error). Second, it is hard to
remember what is the meaning of each numbered placeholder.

This commit adds named placeholders of the form @@{name}. For APIs that
have only one argument short form @@ is still recognized (if the longer
form failed), but for multi-argument APIs only named form is allowed.

It is possible to globally override @@ with any string, for example to
have placeholders of the form ${name} or #{name}.
2020-06-10 23:14:04 +01:00
Ulya Trofimovich 92cbf8fb76 Add generic API for fixed tags.
List of changes:

- Generic APIs YYSHIFT, YYSHIFTSTAG, YYSHIFTMTAG have been added.

- Generic APIs YYSTAGPD, YYMTAGPD have been removed. They were needed
  for STADFA operations, which are now expressed using YYSTAGP /
  YYSHIFTSTAG and YYMTAGP / YYSHIFTMTAG.

- Test results for tests that use generic API have been updated. Some
  variable tags have turned into fixed tags. Tests with fixed-length
  trailing context that do not use tags are no longer erroneous. All
  skeleton tests now need to define new API primitives. STADFA tests
  that use mtags now use YYMTAGP / YYSHIFTMTAG instead of YYMTAGPD.
  Golang test with `re2c:decorate = 1;` that used tags in a hacky way
  via pointers has been removed, because fixed tags cannot be handled
  (and there is a better alternative with `re2c:decorate = 0;`).
2020-06-10 23:03:29 +01:00
Ulya Trofimovich e40d830dcf Merge pull request #287 from trofi/master
configure.ac: store auxiliary configure files in build-aux/
2020-06-07 14:39:26 +01:00
Sergei Trofimovich d63af41a55 configure.ac: store auxiliary configure files in build-aux/
This makes root directory less cluttered. Autoconf-specific
scripts like 'config.guess'. 'install-sh' and friends
are moved to build-aux/ now.

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2020-06-07 14:27:26 +01:00
Ulya Trofimovich 7cbec86cdb Update fixed-length trailing context before tags fixed on cursor.
This fixes bug #286 "Incorrect submatch values with fixed-length
trailing context.". The bug was introduced in commit
a27e6e232f.
2020-06-06 14:20:43 +01:00
Ulya Trofimovich 48b0c8fa2b Fix the use of API primitives in code generation of tag actions.
Changes:
- Allow defining YYMTAGP / YYMTAGN / YYMTAGPD with default API. These
  primitives have no sensible defaults, so they always have to be
  defined by the user.
- Don't generate semicolons with `re2c:decorate = 0;`.
- Generate semicolons in certain cases when they were missing.
- Add a TODO about generic API primitives for fixed tags.
2020-06-04 07:16:52 +01:00
Ulya Trofimovich 4253577f47 Use yyeof label prefix instead of yyeofrule.
Previously `yyeof` prefix was used for YYFILL labels in EOF rule mode,
but now they always use `yyFillLabel` prefix, so the shorter `yyeof`
is available for use in the EOF rule final state.
2020-06-02 23:39:57 +01:00
Ulya Trofimovich e6d16189a4 Further simplify YYFILL code generation. 2020-06-02 23:31:15 +01:00
Ulya Trofimovich e4a9119dc6 Don't output space between YYFILL and the opening parenthesis. 2020-06-02 22:51:51 +01:00
Ulya Trofimovich a9ba9fbf6c Deduplicate YYFILL generation code with and without EOF rule. 2020-06-02 22:45:13 +01:00
Ulya Trofimovich c2656e8135 Deduplicate YYSETSTATE generation code with and without EOF rule. 2020-05-31 22:55:32 +01:00
Ulya Trofimovich cef7dd594b Don't generate redundant semicolons after statements.
With `re2c:decorate = 1;` there should be no semicolon, as the user
should be able to fully control the generated text. With Go backend
there should be no semicolon because it is useless.
2020-05-31 21:08:26 +01:00
Ulya Trofimovich 8c7480da04 Makefile.am: fix dependencies of target docs.
Documentation depends on examples, but the build rule was not properly
updated after examples have been updated.
2020-05-31 18:45:42 +01:00
Ulya Trofimovich 45e9363018 Don't emit YYFILL check when the if body is empty. 2020-05-31 18:33:50 +01:00
Ulya Trofimovich 6ffc3ea15e Update examples, add a script to compile and run them. 2020-05-31 18:15:49 +01:00
Ulya Trofimovich ec82927f18 Test the generated output for documentation examples. 2020-05-31 18:02:37 +01:00
Tony Finch e9764de355 Add a C preprocessor lexer to the tests.
Signed-off-by: Tony Finch <dot@dotat.at>
2020-05-31 16:35:43 +01:00
Ulya Trofimovich c7f27e2e9c Move tests to subdirectory where they belong. 2020-05-27 07:52:41 +01:00
Ulya Trofimovich e61b71eabb Small cleanup in options handling code.
- Transform a few methods into functions to prevent accidental change
  of class members (a function can accept parameters as read-only, or
  not have them passed at all).

- Add methods `reset_<X>` for all options and use them.

- Add comments clarifying that user-defined options and default flags
  should not be modified by the "fix" function.

- Reorder a few blocks in the "fix" function (no functional changes).

- Add a helper function for encodings.
2020-05-27 00:12:18 +01:00
Ulya Trofimovich 130a23706f Clean up re2c:startlabel configuration, add autogenerated tests.
This patch maked the following changes to code generation:

- Ensure that string `re2c:startlabel` configuration takes priority over
  boolean `re2c:startlabel` configuration (this preserves the behavior
  of previous re2c versions).

- In `-c` mode, if start label is forced, emit it only for the first
  condition. For other conditions it's useless, as they already have
  `yyc_<condition>` labels. Besides, numerical start labels would have
  unstable numbers, and text start labels would have the same name for
  different conditions (duplicate labels is an error).

Some tests have been removed as they are covered by the newly added
autogenerated tests.
2020-05-25 10:47:39 +01:00
Ulya Trofimovich ab45b5e3de Get rid of useless label increment.
For historic reasons in `-c` mode re2c started label enumeration from 1
rather than 0. Label 0 is reserved for the start state with `-f` option,
or if the start label is explicitly set with `re2c:startlabel`
configuration. In other cases there is no reason to skip index 0 (except
to avoid changes in the generated code). This patch makes a small change
in the code and drops the artificial increment.

The changes in tests are trivial: label numbers have been decreased
by 1 (or by 2, 4, etc. in tests with multiple reuse blocks). The
following perl script decrements all labels in the code generated by
re2c before the change (old.c) and compares the result (old1.c) with the
new code (new.c). The expected diff is empty. This doesn't work for all
tests (e.g. reuse mode), but in most cases it is enough to verify that
nothing else has changed:

    perl -pe 's/(yy|YYDEBUG\()(\d+)/($1).($2-1)/eg' old.c > old1.c
    diff old1.c new.c
2020-05-24 21:44:59 +01:00
Ulya Trofimovich 9e4299ee7d Decouple start label and initial label.
Start label is needed in `-f` mode: it points to state 0 (the beginning
of block, before condition dispatch in `-c` mode). Initial label points
to the beginning of the DFA (after condition dispatch in `-c` mode).
Previously re2c reused the same label in cases when both start and
initial labels were needed and could be placed adjacent to each other.
Aliasing made it difficult to change the code, because changes of the
start label affected the initial label (and caused massive diffs in the
tests due to a shift in the label numbers).

This patch decouples the labels: now start label, if needed, has its own
label, and initial label always has it own label.

There are 29 changed tests. The changes can be grouped in 3 categories:

1. Trivial renumbering of labels. In most cases all labels except `yy0`
   (which is the start label) have been shifted by 1. It is possible to
   mechanically ensure that nothing else has changed using this script:

    for f in `find . -name '*.orig'`; do
        sed -r 's/(.*)(yy)([1-9][0-9]*)(.*)/cat << EOF\n\1\2$((\3 + 1))\4\nEOF/ge' $f > $f.mod
    done

   In most cases the ".mod" file (which is generated from the original
   test result by incrementing all labels with sed) is identical to the
   new tests result. In some cases manual verfication is necessary
   because labels shifted by a varying number (e.g. due to multiple
   reuse blocks in one file: shift was 2 for the first block, 4 for the
   second block, etc.).

2. Flip of adjacent user-defined start label and re2c-defined start
   label. This happened because previously re2c-defined start label
   aliased to the initial label (which is emitted after the user-defined
   start label), and re2c generated the the initial label (the start
   label was hidden). Now there is no alias, and start label is no
   longer hidden. The change is harmless because user-defined start
   label and re2c-defined start label are always generated next to each
   other.

3. Added jump from the start label to the initial label. Previosly the
   state dispatch jumped directly to the initial label, and now it jumps
   to the start label, and from there to the initial label. The extra
   jump should be trivial to optimise for the compiler.
2020-05-24 10:44:09 +01:00
Ulya Trofimovich f1173a92bf Generate start label for each reuse block in storable state mode.
With `-f` each reuse block has its own state dispatch, and it needs its
own start label as well. Previously the initial state dispatch always
used label 0 (the start label of the first block), which is incorrect
for all but the first blocks.

This partially fixes #282 "Options -f, -c and -r do not combine well".
2020-05-23 12:44:20 +01:00
Ulya Trofimovich a4f799b1b0 Enable reuse mode for autogenerated tests that use storable state.
Previously the combination of `-r` and `-f` could not be used because
the generated code was inconsistent at least (or even incorrect). Now
that the combination has been fixed, it can be used for tests.
2020-05-23 00:08:07 +01:00
Ulya Trofimovich 8d16e96965 Backup and restore default flags together with options.
This partially fixes #282 "Options -f, -c and -r do not combine well".
2020-05-23 00:07:56 +01:00
Ulya Trofimovich 8f8d71e310 Generate non-overlapping YYFILL labels for reuse blocks.
Since all reuse blocks have their own enumeration of YYFILL states
starting from zero and their own state dispatch (not shared with other
blocks, as in the case of non-reuse blocks), YYFILL labels in reuse
blocks have identical indices. This patch adds block ID infix to such
labels in order to prevent label collision if blocks are located in
the same function.

This partially fixes #282 "Options -f, -c and -r do not combine well".
2020-05-23 00:07:45 +01:00
Ulya Trofimovich a7542f2b1e Do not accumulate options from rules/reuse blocks in whole-program options.
This is necessary for consistency with YYFILL states (`-f` option),
which are block-local in reuse mode (`-r` option).

Re2c only recently started to allow mixing reuse and normal blocks,
and the primary user was re2c own lexer, so this change is unlikely
to break anyone.

This partially fixes #282 "Options -f, -c and -r do not combine well".
2020-05-23 00:07:35 +01:00
Ulya Trofimovich c9e69e00c9 Keep track of block-local YYFILL state information.
In `-f`, `--storable-state` mode re2c accumulates information about
YYFILL labels and fallback transitions (for EOF rule). For non-reuse
blocks this whole-program information is used to generate one common
state dispatch. Reuse blocks are handled differently: they have each
their own state dispatch, and YYFILL label numbers starting form zero.

Previously re2c incorrectly handled reuse blocks: instead of using
block-local list of states it used the list from the last block. This
patch fixes it.

This partially fixes #282 "Options -f, -c and -r do not combine well".
2020-05-23 00:07:24 +01:00
Ulya Trofimovich 217158707e In reuse mode, use block-local options instead of last block options.
Last block options are used as "global" or "final" options in certain
cases for code generation: namely, when generating state dispatch and
condition enum, which are accumulated over all blocks. In reuse mode,
however, state dispatch is generated in every block, so it should use
block-local options.

This partially fixes #282 "Options -f, -c and -r do not combine well".
2020-05-23 00:05:36 +01:00
Ulya Trofimovich 292a8b0579 Use reuse mode in test generator for configurations.
Exception: don't reuse mode for tests that set `-f` option and
check `YYGETSTATE` and initial state dispatch, as this mode is
broken (re2c always uses configurations of the last block).
2020-05-21 22:36:59 +01:00
Ulya Trofimovich a4ae442448 Add tests for re2c:placeholder configuration.
Rework test generator for re2c configurations.

Also, don't reset options `re2c:decorate` and `re2c:placeholder` to
defaults (the latter is necessary in order to make the new tests pass).
2020-05-21 07:15:58 +01:00
Ulya Trofimovich 8bbce1be59 Add configuration re2c:placeholder.
This is an umbrella option for options like `define:YYFILL@len`,
`define:YYSETCONDITION@cond`, `define:YYSETSTATE@state` etc.

Default value is "@@".
2020-05-19 22:44:38 +01:00
Ulya Trofimovich 5ecfafc277 Go backend: add conditions support (fix generation of conditions enum). 2020-05-19 21:29:59 +01:00
Ulya Trofimovich 19329aea47 Respect re2c:decorate when generating code for trailing context. 2020-05-19 21:16:36 +01:00
Ulya Trofimovich 674f33c0a6 Go backend: add a test for m-tags (slices and trie implementations). 2020-05-19 00:04:41 +01:00
Ulya Trofimovich 8a56d105c2 Go backend: reformat the "generated by" comment to match guidelines.
The correct form (suggested by `go help generate`) is:
    ^// Code generated .* DO NOT EDIT\.$
2020-05-18 22:30:55 +01:00
Ulya Trofimovich 58c2955d0e Go backend: add a test for posix captures. 2020-05-18 21:51:16 +01:00
Ulya Trofimovich 0143f11e4d Go backend: add a test for Unicode encodings and reuse mode. 2020-05-17 23:16:48 +01:00
Ulya Trofimovich 7330c4aca6 Go backend: emit an error if -g, --computed-gotos option is set. 2020-05-17 22:03:58 +01:00
Ulya Trofimovich cd87899c4f Go backend: support -b, --bit-vectors option. 2020-05-17 21:55:35 +01:00
Ulya Trofimovich 2e23583345 Add an alias for generating a newline. 2020-05-17 10:26:41 +01:00
Ulya Trofimovich 089ec8b5a5 Do not add hoisted tags to fallback transitions.
A precondition to hoisting tag operations out of conditional branches
is that all transitions agree on tags, including the potential fallback
(final or default) transition. Therefore tag operations should not be
repeated on fallback transition. With s-tags repeating is redundant but
harmless, but with m-tags it could cause incorrect submatch results.
2020-05-17 09:45:50 +01:00
Ulya Trofimovich 16d26c378e Inline fallback transitions in state dispatch (to avoid jumping to nested blocks).
Previously with the combination of -f, --storable-state option and EOF
rule re2c generated `yyeof<k>` labels in the default branch of each
state. These labels were used as `goto` targets in the initial state
dispatch. Since Golang does not support jumps into nested blocks, this
patch removes `yyeof<k>` labels and inlines the corresponding fallback
transitions into the state dispatch.
2020-05-17 09:44:42 +01:00
Ulya Trofimovich 9b24f33077 Don't reserve usused initial label for skeleton programs.
This was a weird special case in order to preserve code generation
results during the major rework of the code generation subsystem. It is
no longer needed, as the changes in tests are trivial, concern only a
few skeleton tests and can be checked manually (they are caused by a
shift in label numbers).
2020-05-16 10:38:23 +01:00
Ulya Trofimovich 37a9c4c87a Clean up code generation of default case in switch statements. 2020-05-16 10:08:05 +01:00
Ulya Trofimovich 62ffb97b16 Render switch statements more uniformly.
`switch` statements occur in a few contexts in re2c output: switch on
input symbol, initial switch on conditions (with -c), initial switch on
state (with -f), switch on `yyaccept`. Previously different cases were
rendered in a slightly different way (some cases on the same line, some
on a new line; differences in spaces/tabs).

Now all `switch` statements are rendered uniformly (each case on a new
line), except for switch on input symbol which is unchanged (each cases
on the same line except for cases that contain multiline statements
like tag operations, skip with --eager-skip, or YYFILL with EOF rule).
It would be too difficult to change them, as they constitute the larger
part of re2c output. Also, this would make the generated code less
readable (one-line cases look condensed and aligned).

Massive changes in tests are trivial.
2020-05-16 09:23:28 +01:00
Ulya Trofimovich a67ead3c96 Simplify code generation for switch on yyaccept. 2020-05-16 00:00:36 +01:00
Ulya Trofimovich 750a9aae78 Clean up goto elision. Apply it more aggressively with EOF rule.
Previously goto elision was implemented by passing a null target state
instead of the actual DFA state to the code generation function. However
that prevented goto elision in some other cases with EOF rule, because
the decision whether to elide or not was based on the target state
(which was force-set to null).

This patch adds an explicit "elide" flag instead of the null "hint".
2020-05-15 23:39:49 +01:00
Ulya Trofimovich 1df2b53617 Use proper if statement for code generation of state dispatch. 2020-05-15 07:22:34 +01:00
Ulya Trofimovich 453ca516d6 Go backend: add test for YYFILL (without EOF rule) combined with -f.
The combination of YYFILL with EOF rule and `-f` remains a problem due
to the Go limitation: the language disallows jumping into inner blocks
(re2c generates `yyeof<N>` labels inside of conditional branches).
2020-05-15 07:22:15 +01:00
Ulya Trofimovich fd0b415076 Rework autogenerated tests for options related to API decorations.
Also, forbid using EOF rule with `re2c:yyfill:check = 0;`, as this
combination doesn't make sense (with EOF rule the check is necessary
to distingush sentinel symbol from EOF). Previously this configuration
was not supported (the check was generated despite the option).

The new tests are less uniform than the old tests: some of them contain
multiple blocks (when it is necessary to check the effect of previous
block settings on the next block), and some of them consist of multiple
files with a single block (when the tested part of the generated code
appears once per file, not once per block).

The new tests cover more cases: they add EOF rule and `re2c:decorate`,
`re2c:yyfill:check` configurations, as well as new combinations of
previously tested options.

All test cases are generated using one Haskell script.
2020-05-13 23:43:07 +01:00
Ulya Trofimovich 71f0c9825b Align default value of 're2c:*:naked' options with 're2c:decorate'.
Now instead of always defaulting to false, 're2c:*:naked' options
default to the value of 're2c:decorate' (unless they are explicitly set
by the user). The idea behind this change is to allow the user set one
option instead of a dozen, while still allowing a more fine-grained
control if necessary.
2020-05-10 18:29:55 +01:00
Ulya Trofimovich 7e865ffec8 Add static cast to silence '-Wsign-compare' warning with -m32. 2020-05-10 10:25:48 +01:00
Ulya Trofimovich 30e32a47f7 Add static cast to silence '-Wformat' warning with -m32. 2020-05-10 10:24:41 +01:00
Ulya Trofimovich 25e091912a Go backend: change default options (set generic API, unset decorations).
It is necessary to have different sets of default mutable options for
different language backends. For example, all Go programs need to set
generic API, so it makes sense to set it by default.

The difficulty in changing default mutable options based on the constant
(global) options is that re2c allows to intermix mutable and constant
options on the command line. Therefore by the time all constant options
have been parsed, some of the mutable options may have already been set.
It is impossible to tell which of them have been set from the option
values, because a user-set value may coincide with the default value.
Therefore this commit adds boolean flags indicating if a mutable option
has been explicitly set.
2020-05-10 10:05:06 +01:00
Ulya Trofimovich 9d827a9db0 Add configuration 're2c:decorate'.
Also, add more tests for the Go backend that exercise the new option.
Update existing Go tests.

The new configuration has boolean values (zero is false, non-zero is
true). The default value is true. It is mostly useful with generic API.
It decides whether to generate decorations (e.g. parentheses "()") after
the invocation of YYPEEK, YYSKIP, etc. By setting 're2c:decorate = 0;'
it is possible to avoid functional style calls and generate more
free-form code for API primitives.

In the future this is meant to be an umbrella configuration for various
existing "re2c:define:X:naked" configurations.
2020-05-09 10:26:18 +01:00
Ulya Trofimovich 1e6e0fc08d Go backend: add a test for 'yyaccept'. 2020-05-08 15:15:56 +01:00
Ulya Trofimovich f54a858b42 Go backend: add a test for buffer refill without EOF rule.
Also, update the test for buffer refill with EOF rule.
2020-05-08 12:03:58 +01:00
Ulya Trofimovich e129c218d1 Go backend: generate valid YYMAXFILL and YYMAXNMATCH definitions (as variables). 2020-05-07 23:23:39 +01:00
Ulya Trofimovich deeac885da Clean up code generation related to the input API.
One changed test is caused by correctly generating delayed skip
statement, which opens up new possibilities for combine pass.
2020-05-07 07:56:50 +01:00
Ulya Trofimovich 309e602035 Go backend: don't generate semicolon after statements. 2020-05-06 22:55:22 +01:00
Ulya Trofimovich 3b74518466 Fixed error in YYMAXNMATCH usage example in the docs.
Reported by Konstantin Sobolev.
2020-05-05 23:18:58 +01:00
Ulya Trofimovich b4f0a703b2 Clean up bitmap code generation.
Changes in the tests are trivial (despite large diffs). They are caused
by removal of redundant curly braces and one extra level of indentation
(previously generated in order to reduce the scope of bitmap
declaration, but useless because there are zero bitmaps in this case).
2020-05-05 23:11:03 +01:00
Ulya Trofimovich 653b584602 Rename files and merge a few small headers into one. 2020-05-03 22:56:02 +01:00
Ulya Trofimovich 385e9686dc Rename files. 2020-05-03 11:15:59 +01:00
Ulya Trofimovich 82bfdc03f4 Merge a few headers into one. 2020-05-03 11:15:47 +01:00
Ulya Trofimovich 0a313152f8 Rename a few code generation primitives, clean up redundant structs. 2020-05-03 09:53:51 +01:00
Ulya Trofimovich 1cc7d457c3 Port code generation for goto statements on the new output subsystem. 2020-05-03 09:13:05 +01:00
Ulya Trofimovich 9bb515e737 Add missing fallback states with EOF rule.
When EOF rule is used, a final state may be a fallback state even if
all outgoing paths from it are accepting, because the possibility of
YYFILL failure cretes additional default quasi-transition.
2020-05-01 23:39:52 +01:00
Ulya Trofimovich e6fd8997cd Split transform code generation pass into expand and combine passes.
The "expand" pass generates code for stubs: parts of the code that
cannot be generated during the first code generation pass, because they
require some information that only becomes available after the full
program has been generated.

The "combine" pass folds sequences of simple skip/peek/backup statements
into complex statements. For example, it transforms two-statement
sequence 'yych = *YYCURSOR; ++YYCURSOR;' into 'yych = *YYCURSOR++;'.

Also, render yyeof<N> labels properly (without indentation) and don't
generate an empty statement after them unless they are at the end of a
block.
2020-05-01 20:53:27 +01:00
Ulya Trofimovich fbb2deb395 Delay code generation for labels until the full program is constructed. 2020-05-01 20:53:27 +01:00
Ulya Trofimovich abaeec3dc0 Reuse yyfillLable<N> labels with EOF rule.
Previously labels of the form yyfillLable<N> were used only with -f,
--storable-state option. With EOF rule re2c generated label names
with underscores (unless -f was also enabled). Now re2c always uses
labels of the form yyfillLable<N>.
2020-05-01 20:53:27 +01:00
Ulya Trofimovich 4567a8ae5a Store used label flag in the label struct. 2020-05-01 20:53:07 +01:00
Ulya Trofimovich 0d6edd9f2e Add forgotten header include. 2020-04-27 07:56:37 +01:00
Ulya Trofimovich 50c81ccff3 Move code transformation functions to a separate file. 2020-04-27 07:54:21 +01:00
Ulya Trofimovich 60373d7f26 Move code rendering functions to a separate file. 2020-04-27 07:29:31 +01:00
Ulya Trofimovich 65f79ef715 Rename a few types and functions. 2020-04-26 11:18:23 +01:00
Ulya Trofimovich 554a86496b Remove trivial typedef. 2020-04-26 10:37:41 +01:00
Ulya Trofimovich 9d00c7cbeb Renamed type Code to SemAct to avoid name clash with code generation types. 2020-04-26 00:52:11 +01:00
Ulya Trofimovich 0125650e1d Use generic type and functions for various lists in code generation. 2020-04-26 00:22:57 +01:00
Ulya Trofimovich 7e116ac1eb Avoid using complex expressions in function arguments.
Although the current behavior was ok (only one of the arguments was
a complex expression, and it didn't rely on side-effects), such code
patterns are error-prone and may cause subtle bugs in the future.

Note:

Re2c uses C++98 standard. C++11 adds some guarantees in section 1.9.15:
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf):

  Every evaluation in the calling function (including other function
  calls) that is not otherwise specifically sequenced before or after
  the execution of the body of the called function is indeterminately
  sequenced with respect to the execution of the called function.

And a footnote:

  In other words, function executions do not interleave with each other.

But it is does not solve the problem of possible side-effects.
2020-04-25 21:28:21 +01:00
Ulya Trofimovich 1cb46010c3 Add code generation primitives for functions (used in skeleton). 2020-04-25 10:23:28 +01:00
Ulya Trofimovich 2bf3fdf571 Reuse "raw" code statement kind for DOT code generation. 2020-04-24 00:17:18 +01:00
Ulya Trofimovich 89be91f3df Rewrite recursion into iteration (estimation of NFA size for RE).
This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Partial fix for #219 "overflow-1.re test fails on system with small stack".
2020-04-23 23:02:21 +01:00
Ulya Trofimovich 4d9c809355 Rewrite recursion into iteration (nullable RE).
This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Partial fix for #219 "overflow-1.re test fails on system with small stack".
2020-04-23 22:16:51 +01:00
Ulya Trofimovich 7b5643476b Rewrite recursion into iteration (fixed tags computation).
This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Partial fix for #219 "overflow-1.re test fails on system with small stack".
2020-04-22 22:37:24 +01:00
Ulya Trofimovich fd634998f8 Rewrite recursion into iteration (Tarjan's SCC algorithm and YYFILL states).
This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Stack overflow reported by Agostino Sarubbo.
Related to #219 "overflow-1.re test fails on system with small stack".
2020-04-21 23:04:51 +01:00
Ulya Trofimovich 637d4e4688 Rewrite recursion into iteration (paths for -Wundefined-control-flow).
This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Stack overflow reported by Agostino Sarubbo.
2020-04-19 22:48:09 +01:00
Ulya Trofimovich e3e43bcbb7 Rewrite recursion into iteration (skeleton max path length computation).
Ensured that the new algorithm computes the same length as the old one
by adding temporary debug print of the computed length to both
algorithms and verifying that it coincides.

This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Stack overflow reported by Agostino Sarubbo.
2020-04-19 10:48:47 +01:00
Ulya Trofimovich 7b689f4231 CMake: force colored compiler messages with -fdiagnostics-color=always. 2020-04-19 09:07:24 +01:00
Ulya Trofimovich f39b522cd4 Rewrite recursion into iteration (insertion of negative tags in RE).
This is to avoid stack overflow on large RE (especially on instrumented
builds that have larger stack frames, like AddressSanitizer).

Stack overflow reported by Agostino Sarubbo.
2020-04-18 19:33:22 +01:00
Ulya Trofimovich 5f19bee152 Travis CI: add skeleton tests, use Debug -O2 instead of RelWithDebInfo for CMake.
RelWithDebInfo build type disables asserts, which is bad for testing.
2020-04-18 11:07:58 +01:00
Ulya Trofimovich 38034eabe5 Give an explicit error if skeleton is used with non-C language backend. 2020-04-18 10:11:19 +01:00
Ulya Trofimovich 6189985225 Skip skeleton tests for non-C language backends.
Currently --skeleton option can only generate a C program, other
languages (such as Go) are not supported.
2020-04-18 10:00:01 +01:00
Ulya Trofimovich 1503a74509 Use block number in EOF label.
This allows to use EOF rule with multiple blocks in the same function
(previously re2c generated duplicate EOF labels, so the code did not
compile).

This fixes bug #280: "EOF rules with multiple blocks", reported by brk.
2020-04-18 09:19:02 +01:00
Ulya Trofimovich b85dac9676 CMake build scripts: use Debug -O2 instead of RelWithDebInfo build flavor.
RelWithDebInfo keeps debug information, but also sets NDEBUG, which
disables asserts. For development, it is necessary to enable
optimizations, debug info and asserts (and also the additional debug
checks enabled with RE2C_DEBUG).
2020-04-17 23:40:15 +01:00
Ulya Trofimovich c4603ba5ce Fix crash in lexer refill (reported by Agostino Sarubbo).
The crash happened in a rare case of a very long lexeme that doen't fit
into the buffer, forcing buffer reallocation.

The crash was caused by an incorrect calculation of the shift offset
(it was smaller than necessary). As a consequence, the data from buffer
start and up to the beginning of the current lexeme was not discarded
(as it should have been), resulting in less free space for new data than
expected.
2020-04-17 22:47:14 +01:00
Ulya Trofimovich 187fff3a8b Use 'cc' instead of @CC@ for host C compiler in skeleton tests.
CMake and Autoconf do not agree on the name of the variable: CMake uses
CMAKE_C_COMPILER, and Autoconf uses CC. Plain 'cc' doesn't work on systems
that do not have this alias, but it is unlikely that somenone will run
skeleton tests on such systems.
2020-04-17 21:02:55 +01:00
Ulya Trofimovich d6875dff2d Use new output representation for skeleton code generation. 2020-04-17 07:31:55 +01:00
Ulya Trofimovich 8da6666e4b Add forgotten header include. 2020-04-15 07:59:23 +01:00
Ulya Trofimovich 9565237bec Merge remote-tracking branch 'origin/golang-backend' 2020-04-15 07:51:06 +01:00
Ulya Trofimovich 14c5bea658 Total rewrite of the code generation subsystem.
Previously the output program was represented as a list of blocks (one
block per each re2c comment in the source file). Each block consisted
of a list of heterogenous fragments. Some fragments contained text that
was generated immediately during the first pass of code generation;
other fragments were placeholders for parts of the program whose
generation was delayed (such as dispatch on YYFILL labels with -f option
that cannot be generated on the first pass because the full list of
labels is known only at the end of the first pass). Individual fragments
used ad-hoc methods to render the generated code, which made rendering
rather complex (for example, it was problematic to decide if the 'if'
statement should be rendered on a single line or on multiple lines).

This commit adds a new AST-like representation of the output program.
The top-level program is still a list of output blocks, but each block
is now an AST. This decouples code generation from rendering, which
simplifies both phases and allows easier customization for different
output language backends (such as C or Go).
2020-04-15 07:04:54 +01:00
Ulya Trofimovich faa5d410e5 Add tests for conditions enum with and without header file. 2020-04-13 18:12:13 +01:00
Ulya Trofimovich 9405f850a4 CMake: added comment, cosmetic formatting changes. 2020-04-11 08:39:25 +01:00
Ulya Trofimovich 9ffd690c59 Merge pull request #279 from ligfx/patch-1
CMake: only add `check` target if toplevel project
2020-04-11 01:41:56 +01:00
ligfx 907fd7dc76 CMake: only add check target if toplevel project 2020-04-10 16:18:34 -07:00
Ulya Trofimovich edab559abe Travis CI: update comment. 2020-04-09 07:42:38 +01:00
Ulya Trofimovich 702f19b2d8 Travis CI: add more cmake configurations. 2020-04-09 07:22:39 +01:00
Ulya Trofimovich d48066350d CMake: add DESTINATION to install() for compatibility with cmake-3.12.4.
Otherwise on Travis CI cmake-3.12.4 fails with errors like:

  CMake Error at CMakeLists.txt:206 (install):
    install TARGETS given no RUNTIME DESTINATION for executable target "re2c".

  CMake Error at CMakeLists.txt:356 (install):
    install TARGETS given no ARCHIVE DESTINATION for static library target
    "libre2c_static".

  CMake Error at CMakeLists.txt:365 (install):
    install TARGETS given no LIBRARY DESTINATION for shared library target
    "libre2c_shared".
2020-04-09 00:18:49 +01:00
Ulya Trofimovich 7ab95bb142 Travis CI: add experimental cmake configuration. 2020-04-09 00:04:30 +01:00
Michael Maltese b85de4e29b CMake: clean up generator expression checking for Windows 2020-04-07 21:22:40 +01:00
Michael Maltese 80cd01b587 Add CMake build scripts 2020-04-07 20:55:55 +01:00
Ulya Trofimovich 43528ddf3b CMake: add test_libre2c to make check.
Tested as:
    $ cmake -DRE2C_BUILD_LIBS=on  -B build && cd build && make check
    $ cmake -DRE2C_BUILD_LIBS=off -B build && cd build && make check
2020-04-07 00:07:24 +01:00
Ulya Trofimovich 29da9fae2b CMake: correctly set dependency on run_test.sh for testing targets.
The dependency should be relative to the build directory.

Tested as:
    $ cmake -B build && cd build
    $ make && make tests
(previously failed to build dependency run_tests.sh, now finishes
successfully).
2020-04-06 23:43:36 +01:00
Ulya Trofimovich d72d005f39 CMake: comment why static lib suffix is needed on Windows and use a generator expression. 2020-04-06 23:01:38 +01:00
Ulya Trofimovich 83f7bc8881 Merge branch 'ligfx-cmake' 2020-04-06 21:01:09 +01:00
Michael M a530570e51 Add a CMake build system
Invoke it like this on Unix:

mkdir build
cd build
cmake .. \
  [-DCMAKE_C_FLAGS=...] [-DCMAKE_CXX_FLAGS=...] \
  [-DCMAKE_EXE_LINKER_FLAGS=...] \
  [-DCMAKE_SHARED_LINKER_FLAGS=...] [-DCMAKE_STATIC_LINKER_FLAGS=...] \
  [-DCMAKE_C_COMPILER=...] [-DCMAKE_CXX_COMPILER=...] \
  [-DCMAKE_BUILD_TYPE=Debug|Release|RelWithDebInfo] \
  [-DRE2C_REBUILD_DOCS=YES] \
  [-DRE2C_BUILD_LIBS=YES [-DBUILD_SHARED_LIBS=YES|NO]] \
  [-G Ninja]
make -j # or ninja, if "-G Ninja" was used

Or on Windows, install Visual Studio's CMake tools and then open this folder.
2020-04-05 10:09:21 -07:00
Ulya Trofimovich 147fbd25e9 Do not omit labels before final non-end states when EOF rule is used.
These labels are used by the code that handles unsuccessfull YYFILL:
the lexer falls back to the final state.

This fixes bug #276 "Example 01_fill.re in docs is broken"
(reported by Angelo Haller).
2020-04-03 23:48:17 +01:00
Ulya Trofimovich 35d3ef12cd Go backend: fixed code generation for the case of EOF rule and buffer refilling.
Namely, fixed the generation of 'yyaccept' declaration and added braces
in the 'if' statement. Added a test that uses 'YYFILL' and EOF rule.
2020-03-27 22:34:03 +00:00
Ulya Trofimovich 4f24b1237b Go backend: emit correct 'yych' declaration. 2020-03-25 23:47:14 +00:00
Ulya Trofimovich f285438b6e Go backend: generate '.go' filename extension for Go tests. 2020-03-25 23:24:02 +00:00
Ulya Trofimovich 6e7f0379ff Go backend: generate correct line directives. 2020-03-25 23:02:25 +00:00
Ulya Trofimovich 61253e1969 Add a more generic option '--lang <c | go>' instead of '--golang'.
This is more extensible in case re2c needs to add a backend for some other
language. The "lang" option is now separate from the "target" option.
2020-03-25 22:37:34 +00:00
Ulya Trofimovich b7facb2192 Go support: added 'fallthrough' in goto statements. Added the first test. 2020-03-25 00:16:27 +00:00
Ulya Trofimovich 30738b9482 Initial support for Go: adding Go target and --golang option. 2020-03-24 23:37:42 +00:00
Ulya Trofimovich 8276d9b149 Revised the paper "Efficient POSIX submatch extraction on NFA".
Changes:
- added an example of TNFA
- added an example of how mark() and enum() work
- changed the explicit submatch index to a set of indices to simplify handling
  of repeated captures like ((e))
- changed benchmarks and their representation: use horizontal bar charts instead
  of linear plots
- added naming conventions and renamed the variables throughout the paper
- re-worded the abstract and introduction
- multiple small tweaks
2020-03-12 23:37:07 +00:00
Ulya Trofimovich e0b4f738f2 libre2c: Updated benchmarks. 2020-03-07 20:21:18 +00:00
Ulya Trofimovich 662b45ef46 Merge pull request #271 from samebchase/patch-1
Fix typo in README.md
2020-03-05 13:24:05 +03:00
Samuel Chase 93c59de149 Fix typo in README.md 2020-03-05 14:38:47 +05:30
Ulya Trofimovich 38f3df7721 Removed incorrect TODO comment.
The comment suggested to avoid memset of boolean array, which elements
indicate if the tag has already been updated n the current step, with
an array of integers that store step number, and thus do not require
explicit zero-initialization (step numbers are growing monotonously).

After some expreiments this idea doesn't seem so good, because:

- Update function is called multiple times for the same step value (for
  different configurations), thus requiring a more complex marker value
  that would combine step number with configuration id.

- It doesn't seem to be the bottleneck (there is another memcpy, which
  is unavoidable.
2020-02-02 12:41:35 +00:00
Ulya Trofimovich 2082759eb4 libre2c: Deduplicated conversion of tag values to submatch offsets for various algorithms. 2020-02-01 23:25:43 +00:00
Ulya Trofimovich 199c000c41 Collapse repeated captures and store the range of corresponding submatch indices.
For example, (((x))) becomes (x), where the tag for the left parenthesis has
an associated range of submatch indices [0,2,4], and the tag for the right
parenthesis has an associated range [1,3,5].
2020-02-01 21:52:53 +00:00
Ulya Trofimovich 20fdb3c36f libre2c: Store intermediate results as tags (do not convert to submatch indices). 2020-01-29 22:11:03 +00:00
Ulya Trofimovich f8f16f5af6 Output individual tag history trees for TDFA states with '--dump-dfa-tree'. 2020-01-05 11:17:54 +00:00
Ulya Trofimovich cd5c4c86e5 travis.yml: correctly expand shell variable. 2019-12-31 17:08:51 +00:00
Ulya Trofimovich bf1c67f9d7 Added forgotten debug macro stub for non-debug mode.
This fixes bug #266 "New debug macro DDUMP_DFA_TREE missing in non-debug case".
Thanks to HBBroeker for the bug report.
2019-12-31 17:01:34 +00:00
Ulya Trofimovich fbd40379e4 travis.yml: add non-debug build to the matrix. 2019-12-31 16:58:11 +00:00
Ulya Trofimovich d20cec8ca2 Merge pull request #265 from trofi/ccache-ci
.travis.yml: enable ccache to speed up incremental builds
2019-12-27 21:19:20 +00:00
Sergei Trofimovich dd4d9b2a27 .travis.yml: enable ccache to speed up incremental builds
I'm not sure what would be the actual benefit. Let's try it in action!

Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2019-12-27 20:26:20 +00:00
Ulya Trofimovich 3f392d4429 Merge pull request #218 from trofi/travis-sanitizers
.travis.yml: add sanitizers into test matrix
2019-12-27 20:23:21 +00:00
Sergei Trofimovich a44ff29a24 .travis.yml: add sanitizers into test matrix
Bug: https://github.com/skvadrik/re2c/issues/215
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
2019-12-27 20:14:05 +00:00
Ulya Trofimovich 01281ca563 Documented debug option '--dump-dfa-tree'. 2019-12-27 19:06:09 +00:00
Ulya Trofimovich 0a0d9eb5af Added forgotten source file to git. 2019-12-27 19:01:45 +00:00
Ulya Trofimovich 4061c451cf Added debug option '--dump-dfa-tree' that prints tag history trees. 2019-12-27 17:55:29 +00:00
Ulya Trofimovich 434b6874fb Better documentation for debug options. 2019-12-25 21:19:22 +00:00
Ulya Trofimovich 8fddc8bbcd Explicitly documented that internal options are internal and unstable. 2019-12-25 20:54:41 +00:00
Ulya Trofimovich 79c62e4e81 Added internal option '--posix-prectable <naive | complex>'.
The new option allows to specify the algorithm used to compute POSIX precedence
table. The 'complex' algorithm computes precedence table in one traversal of
tag history tree and has quadratic complexity in the number of TNFA states; it
is the default. The 'naive' algorithm has worst-case cubic complexity in the
number of TNFA states, but it is much simpler than 'complex' and may be slightly
faster in non-pathological cases.
2019-12-25 20:31:57 +00:00
Ulya Trofimovich cabebc34a0 Updated re2c version in the manpage. 2019-12-14 11:50:42 +00:00
Ulya Trofimovich e1901b71c6 Release 1.3. 2019-12-14 11:43:05 +00:00
Ulya Trofimovich ca41c365a8 Updated CHANGELOG. 2019-12-13 23:36:16 +00:00
Ulya Trofimovich a55c2bc888 Fixed -Wmissing-prototypes warning. 2019-12-12 07:37:27 +00:00
Ulya Trofimovich fcce896f45 Fixed -Wshadow warning. 2019-12-12 07:29:49 +00:00
Ulya Trofimovich 8f505bf35a Fixed -Wformat warnings on systems with 32-bit size_t. 2019-12-12 07:08:55 +00:00
Ulya Trofimovich fdc4f0b20b Added a fuzz-testing script that checks staDFA vs TDFA. 2019-12-11 23:13:28 +00:00
Ulya Trofimovich a1d38915dc Added staDFA to libre2c (library, test and benchmark).
Note: some REs in the benchmark have too many tag variables with staDFA,
but not with TDFA.
2019-12-11 22:55:55 +00:00
Ulya Trofimovich e2bb60616d Added a few more (non-POSIX) tests for staDFA. 2019-12-11 07:18:40 +00:00
Ulya Trofimovich 51a26ff4b2 Added POSIX tests for staDFA. 2019-12-11 07:16:43 +00:00
Ulya Trofimovich 53d4239f38 Added staDFA to POSIX testing script. 2019-12-11 00:00:58 +00:00
Ulya Trofimovich d729b5f105 Added skeleton support for staDFA. 2019-12-10 23:56:30 +00:00
Ulya Trofimovich d0089f9c46 Implemented staDFA algorithm.
The algorithm is described in the paper "STADFA: An efficient Subexpression
Matching Method" by Mohammad Imran Chowdhury.

The main difference between staDFA and TDFA is in the placement of tag actions:
staDFA places them in states, while TDFA places them on transitions. RE2C
implementation of staDFA differs from the description in the paper in a number
of aspects:

- We use TNFA with epsilon-transitions instead of Glushkov automaton used by
  Chowdhury. Glushkov automaton is not ambiguity-preserving, unless it is
  modified to have multi-transitions between a pair of states, which differ
  only in the tag sequences assigned to them. Such multi-transitions are used
  by the original Okui-Suzuki PAT, but there is a problem with this idea: the
  number of multi-transitions may grow exponentially with the size of RE.

- We use the same disambiguation algorithms as those used for TDFA, not those
  described by Chowdhury.

- We associate tag indices with TNFA states, and not symbols occurrences in RE.
  In principle this is the same: for each occurrence of a given symbol there is
  a distinct TNFA state (the same state corresponds to multiple symbols from
  the same range, but not for multiple occurrences of the same symbol).

- We always use "delayed store" actions, as we need to know the values of tags
  under repetition either on the last iteration (for s-tags), or on all
  iterations (for m-tags).

- We compare lookahead tags when looking for an identical state.

- We compare POSIX precedence matrces when looking for an identical state.

- We use negative tags.

- We don't add "delayed store" actions for lookahead tags of the origin state
  which do not have current transiiton symbol in their lookahead set.

- We create initial transfer actions for all tags and all sub-states of the
  initial state. This ensures that there is an action for every final sub-state.

- We resolve cycles in tag commands using temporary variables.
2019-12-10 22:54:53 +00:00
Ulya Trofimovich 749be69c87 Updated docs for YYSTAGPD and YYMTAGPD configurations. 2019-12-10 07:28:09 +00:00
Ulya Trofimovich 110759bd44 Added configurations YYSTAGPD and YYMTAGPD for staDFA "delayed store" actions. 2019-12-10 07:25:50 +00:00
Ulya Trofimovich 79507076d7 Updated docs for --stadfa option. 2019-12-10 07:23:47 +00:00
Ulya Trofimovich 7d0efb24ba Added option --stadfa. 2019-12-10 07:18:36 +00:00
Ulya Trofimovich 4b78bb9970 Fixed formatting (cosmetic). 2019-12-09 23:45:14 +00:00
Ulya Trofimovich 1ab39d457d Use size_t instead of int32_t to avoid overflow in array index on REs with many tags.
Interference table is square in the number of tag variables, so 32-bit signed
indices into it overflow when the number of tag variables approaches 2^16.
With this fix overflow may still happen on platforms that have 32-bit size_t,
or on REs with too many tags.
2019-12-09 23:12:57 +00:00
Ulya Trofimovich b96092ab54 Consistently remove duplicates when optimizing in tag commands.
Duplicate commands may arise as a result of tag optimizations, and should be
removed in all cases ("set', "copy" and "add" commands). In case of "set"
commands this can be done by sorting commands and removing adjacent duplicates.
In case of "add" commands sorting is not possible, but deduplication can still
be implemented using naive quadratic algorithm. Deduplication of "copy" commands
depends on the presence of cycles (if there are no cycles, it is possible to
sort commands lexicographically, then remove adjecent duplicates, then sort
commands topologically).
2019-12-09 22:58:07 +00:00
Ulya Trofimovich 4e63b087cc Reworked topsort of tag commands to accept end pointer and return the first non-trivial cycle.
Accepting end pointer rather than assuming NULL-terminated list of commands is
convenient when the topsorted list is a sublist in the middle of a larger list.

Returning a pointer to the first non-trivial cycle is needed in ordert to break
the cycle by introducing a temporary variable; this is needed for implementing
staDFA.
2019-12-09 07:43:26 +00:00
Ulya Trofimovich 2adb40ea81 Handle block-local liveness in dead code elimination.
This is needed in preparation for staDFA implementation. Variables local to
basic block may occur as a result of breaking cycles in a sequence of tag
commands by introducing temporary variables. TDFA mappings have no cycles
(such mappings are rejected), but staDFA transfer actions often do, because
the indices used in the actions are bound to TNFA substates, which may be
flipped in the origin and target staDFA states.
2019-12-08 23:57:36 +00:00
Ulya Trofimovich 1322bc25d5 Don't use 'Mrecord' Graphviz shape for '--dump-dfa-raw' output as it doesn't work correctly with HTML labels. 2019-12-08 23:36:16 +00:00
Ulya Trofimovich 8d713fbe39 Skeleton: abort if history length exceeds maximum value of key type.
Ideally we should use different encoding (e.g. always allow 2 or 4 bytes
for history length), but that requires more complex serialization and
deserialization. Assert is a temporary measure.
2019-12-08 23:19:09 +00:00
Ulya Trofimovich 01ad5dccfd Skeleton: make m-tag pool relocatable by using indices instead of pointers.
M-tag pool is reallocated and moved when it runs out of space. However,
previously it contained an array of structs with pointers to elements of this
array. After moving these pointers where no longer valid.
2019-12-08 23:19:09 +00:00
Ulya Trofimovich 36a5f79f40 Don't allocate unused tag variable.
In some cases this was causing increase in the number of tag variables after
optimizations, which is generally bad and also caused memory access violation
as the liveness/interference tables are allocated for the initial number.

The 0-th variable is superficial and does not correspond to a real tag version
(zero is a special version reserved for "no tag operation"). In the variable
allocation algorithm it is convenient to handle zero in the same way as other
variables (because arrays are indexed from zero). In most of the cases 0-th
variable ends up in a class that contains other (non-fake) variables, but if it
is alone in its class, then no tag variable should be allocated for this class.
2019-12-08 23:19:09 +00:00
Ulya Trofimovich 0686c48bfc Don't ignore interference induced by fallback tag commands. 2019-12-08 23:19:08 +00:00
Ulya Trofimovich 1e1a376c05 Reworked CFG construction to allow tags both in states and on transitions.
This is needed in preparation for implementing staDFA algorithm, in which
tag operations are placed in states, not on transitions. The new CFG model
is able to accommodate both TDFA and staDFA, as well as a hypothetical
"mixed" case where tag operations occur both in states and on transitions.

This commit adds "canonical" marking of visited states and transitions, which
allows to avoid erroneous creation of dulicate arcs in the CFG.

Some of the helper functions have been rewritten from recursion to iteration.

This commit also adds CFG construction context to avoid passing too many
parameters to the helper functions.
2019-12-08 23:19:08 +00:00
Ulya Trofimovich 9ac4408a55 Use correct index for the final substate in the .dot output for '--dump-dfa-raw'. 2019-12-08 23:19:01 +00:00
Ulya Trofimovich 4477437525 Prioritize normal rule that matches empty string over EOF rule. 2019-12-08 19:19:43 +00:00
Ulya Trofimovich 4b006d7f00 Do not remove shadowed rules if EOF rule is used.
With EOF rule, it is always possible that EOF happens before the next matching
rule, even if it matches all possible inputs. If EOF does happen, the lexer
needs to rollback to the last matched rule (so it is not dead).
2019-12-08 19:16:39 +00:00
Ulya Trofimovich 45f561e3b2 Moved code that decides on tag hoisting to a separate function with a comment. 2019-12-08 19:13:16 +00:00
Ulya Trofimovich 08508a6342 Changed the decsription of tags in docs to avoid ambiguity.
Thanks to Des-Nerger for pointing out in bug #140.
2019-10-11 07:42:50 +01:00
Ulya Trofimovich 2ee9c50c05 Added ninja lexers to tests.
Note: ninja_lexer.ib.c differs from the original lexer in the ninja project,
because the latter was generated with re2c-0.16, which used slightly
different constructs for complex expressions:

Re2c-0.16 used generated something like this:

    ++YYCURSOR;
    if (yych = *YYCURSOR) ...

And the latest re2c generates something like this:

    yych = *++YYCYRSOR;
    if (yych) ...

The difference is insignificant.
2019-09-01 10:03:48 +01:00
Ulya Trofimovich 94faf98935 Moved tests into subdirectories and deleted some of the largest skeleton tests. 2019-09-01 10:01:44 +01:00
Ulya Trofimovich e34fe4dde7 libre2c: added prefix 'TOKEN_' to all parser tokens to avoid name collisions.
Apparently some versions of bison generate token definitions as macros, not
as enum members. If a bison-generated header is included into another file
that contains identifiers identical to the names of parser tokens, all such
identifiers are macro-substituted to a numeric constant. Adding a prefix to
token names reduces the chances of name collision.

This fixes bug #261: "lib/parse.h:49:15: 错误:expected unqualified-id before
numeric constant" reported by qidizi.
2019-08-29 22:27:01 +01:00
Ulya Trofimovich 269578f8d4 Fixed documentation regarding '...:naked' configurations. 2019-08-28 23:42:01 +01:00
Ulya Trofimovich 257b318439 Respect 're2c:define:YYFILL:naked' and 're2c:yyfill:parameter' configurations with EOF rule.
Thanks to Nazim Can Bedir for the bug report.
2019-08-28 23:10:10 +01:00
Ulya Trofimovich 47f7742d2e Updated documentation for the new 're2c:sentinel' configuration. 2019-08-25 11:17:16 +01:00
Ulya Trofimovich 82d1833970 Added some tests for 're2c:sentinel' configuration. 2019-08-25 10:41:58 +01:00
Ulya Trofimovich de63b8baed Added -Wsentinel-in-midrule warning and 're2c:sentinel' configurations.
The new analysis is meant to detect potential reads past the end of buffer
resulting from erroneous rules that allow sentinel symbol to occur in the
middle of lexeme. The analysis is only activated in cases bounds checking
is disabled with 're2c:yyfill:enable = 0;' and EOF rule is not used.

For example:

    ['] [^']* [']   { ... }

This may be a naive way to match single-quoted strings; it would crash the
lexer on input like "'aaa\0" (without the closing single quote).
2019-08-25 10:22:09 +01:00
Ulya Trofimovich 7648f8dd9e Got rid of PACKAGE_DATE variable altogether (it was used only in the manpage). 2019-08-17 21:39:04 +01:00
Ulya Trofimovich 7e10b11a0a Merge pull request #258 from lamby/934697-re2c-please-make-the-build-reproducible
Make the build reproducible
2019-08-14 07:18:18 +01:00
Chris Lamb a4c0ff1bf8 Make the build reproducible
Whilst working on the Reproducible Builds effort [0] we noticed
that re2c could not be built reproducibly.

This is because it used the current build date in the manual page and was
originally filed in Debian as #934697 [1].

This patch uses the SOURCE_DATE_EPOCH [2] environment variable.

 [0] https://reproducible-builds.org/
 [1] https://bugs.debian.org/934697
 [2] https://reproducible-builds.org/specs/source-date-epoch/

Signed-off-by: Chris Lamb <lamby@debian.org>
2019-08-13 13:53:04 -07:00
Ulya Trofimovich f2df7574a9 Merge pull request #256 from certik/license
Package LICENSE file in the release tarball
2019-08-13 06:54:05 +01:00
Ulya Trofimovich 8449d452d1 Updated bootstrap manpage. 2019-08-13 06:49:26 +01:00
Ulya Trofimovich 78ea5562ba Merge pull request #255 from jcfp/master
fix documentation typos
2019-08-13 06:47:32 +01:00
Ondřej Čertík a933242be9 Package LICENSE file in the release tarball
This is important when re2c is packaged in distributions, so that one can
quickly check what license the re2c is distributed under. Distributions
typically use the release tarball, not the git repository, and so this commit
puts the LICENSE file into the release tarball also.
2019-08-12 22:26:40 -06:00
jcfp f5072bf4ce fix documentation typos 2019-08-12 12:41:10 +02:00
Ulya Trofimovich b644493b05 Release 1.2.1. 2019-08-11 09:38:33 +01:00
Ulya Trofimovich 3a24a0cc07 Updated CHANGELOG. 2019-08-11 09:23:17 +01:00
Ulya Trofimovich c3880fc84e Install standard library files in $(datadir)/re2c/stdlib and search for include files in this location.
This fixes bug #253 "re2c should install unicode_categories.re somewhere"
(reported by Wesley W. Terpstra).
2019-08-07 23:19:21 +01:00
Ulya Trofimovich 27156203d3 Allow to reset 're2c:eof' configuration.
The ability to reset this configuration is necessary in order to be able to
mix re2c blocks that use EOF rule and blocks that don't.

This fixes bug #254: "Turn off re2c:eof".
2019-08-05 23:33:10 +01:00
7244 changed files with 2186365 additions and 1188694 deletions
+97
View File
@@ -0,0 +1,97 @@
name: benchmarks
on:
# allow to trigger manually (on default branch)
workflow_dispatch:
# run once a week
schedule:
- cron: '0 0 * * 0'
defaults:
run:
shell: bash
jobs:
build-and-run:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
# Linux
- name: linux-gcc
os: ubuntu-latest
# macOS
- name: macos-clang
os: macos-latest
# no Windows, as Kleenex generates non-portable C code
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: '3.8'
- name: Setup Java
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
- name: Setup Common Prerequisites
run: |
case ${{ runner.os }} in
Linux*)
echo "CC=gcc" >> $GITHUB_ENV
echo "CXX=g++" >> $GITHUB_ENV
sudo apt install libre2-dev libbenchmark-dev
;;
macOS*)
sudo xcode-select -switch /Applications/Xcode.app
echo "CC=$(xcrun -f clang)" >> $GITHUB_ENV
echo "CXX=$(xcrun -f clang++)" >> $GITHUB_ENV
echo "SDKROOT=$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_ENV
echo "$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_PATH
brew install re2 google-benchmark
;;
esac
pip install psutil
- name: Configure
run: |
cmake -S . -B .build \
-G "Unix Makefiles" \
-DRE2C_BUILD_LIBS=ON \
-DRE2C_BUILD_RE2GO=OFF \
-DRE2C_BUILD_BENCHMARKS=ON \
-DCMAKE_CXX_FLAGS="-O3"
- name: Build
run: cmake --build .build
- name: Run submatch DFA AOT benchmark
working-directory: .build/benchmarks/submatch_dfa_aot
run: |
./run.py --quickverify \
&& ./run.py --repetitions 5 --output results.json \
&& cat results.json
- name: Run submatch DFA JIT benchmark
working-directory: .build/benchmarks/submatch_dfa_jit
run: ./bench_submatch_dfa_jit
- name: Run submatch Java benchmark (ReTdfa)
working-directory: .build/benchmarks/submatch_java
run: ./run.py
- name: Run submatch NFA benchmark
working-directory: .build/benchmarks/submatch_nfa
run: ./bench_submatch_nfa
+160
View File
@@ -0,0 +1,160 @@
name: CI
on:
push:
pull_request:
defaults:
run:
shell: bash
jobs:
build-and-test:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
# When set to true, GitHub cancels
# all in-progress jobs if any matrix job fails.
fail-fast: false
matrix:
include:
# Linux
- name: linux-gcc-ubsan-ootree
os: ubuntu-latest
- name: linux-gcc-asan-ootree
os: ubuntu-latest
- name: linux-gcc-debug-ootree-skeleton
os: ubuntu-latest
- name: linux-gcc-debug-intree-m32-skeleton
os: ubuntu-latest
- name: linux-gcc-release-ootree-skeleton
os: ubuntu-latest
# macOS
- name: macos-clang-debug-ootree-skeleton
os: macos-latest
- name: macos-clang-debug-intree-skeleton
os: macos-latest
- name: macos-clang-release-ootree-skeleton
os: macos-latest
# Windows
- name: windows-msvc-debug-ootree
os: windows-latest
- name: windows-msvc-debug-intree
os: windows-latest
- name: windows-msvc-release-ootree
os: windows-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
- name: Setup chocolatey Cache (Windows)
if: startsWith(runner.os, 'Windows')
uses: actions/cache@v2
with:
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
key: ${{ runner.os }}-chocolatey-${{ matrix.os }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-chocolatey-${{ matrix.os }}-
${{ runner.os }}-chocolatey-
- name: Setup Common Prerequisites
run: |
case ${{ runner.os }} in
Linux*)
sudo apt install gcc-multilib g++-multilib # for -m32
;;
macOS*)
sudo xcode-select -switch /Applications/Xcode.app
echo "SDKROOT=$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_ENV
echo "$(xcodebuild -version -sdk macosx Path)" >> $GITHUB_PATH
;;
Windows*)
choco install --no-progress -y winflexbison3
;;
esac
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.x
architecture: x64
- name: Install Python Dependencies
# Disabled until this https://github.com/skvadrik/re2c/issues/327
# will be implemented
if: startsWith(runner.os, 'Windows') == false
run: |
python -m pip install --upgrade pip
python -m pip install docutils pygments
- name: Check Available Configure Presets
run: cmake --list-presets
- name: Fast Configure
run: cmake --preset=${{ matrix.name }}-fast
- name: Fast Build
run: cmake --build --preset=${{ matrix.name }}-fast
- name: Install
run: cmake --build --preset=${{ matrix.name }}-fast --target install
- name: Minimal Install Test
working-directory: ./install/bin
run: ./re2c --version
- name: Full Configure
run: cmake --preset=${{ matrix.name }}-full
- name: Full Build
run: |
find src -name '*.re' | xargs touch
cmake --build --preset=${{ matrix.name }}-full
- name: Run Main Test Suite
run: cmake --build --preset=${{ matrix.name }}-full --target tests
- name: Get build dir
id: build-info
run: |
if echo "${{ matrix.name }}" | grep -q "ootree"; then
BUILD_DIR="$(pwd)/.build/${{ matrix.name }}-full"
else
BUILD_DIR="$(pwd)"
fi
echo "::set-output name=BUILD_DIR::$BUILD_DIR"
- name: Run Skeleton Tests
if: "contains(matrix.name, 'skeleton')"
# Remove the following line after fix Windows tests
working-directory: ${{ steps.build-info.outputs.BUILD_DIR }}
run: python run_tests.py --skeleton
- name: Archive test artifacts
# Run this step only if tests failed (otherwise there is nothing to upload).
if: failure()
uses: actions/upload-artifact@v2
with:
# To ensure that jobs don't overwrite existing artifacts,
# use a different name per job.
name: test-${{ matrix.name }}
# Tests run in a temporary directory that has a name test_<timestamp>.
path: ${{ steps.build-info.outputs.BUILD_DIR }}/test_[0-9]*
# Artifacts are retained for 90 days by default.
# In fact, we don't need such long period.
retention-days: 30
+18 -2
View File
@@ -1,4 +1,21 @@
autom4te.cache/
# Please do not use this ignore file to define platform specific files
# e.g. autogenerated files by IDE.
#
# For these purposes create a global .gitignore file, which is a list of rules
# for ignoring files in every Git repository on your computer.
#
# https://help.github.com/articles/ignoring-files/#create-a-global-gitignore
# The directories to ignore (do not add trailing '/'s, they skip symlinks).
/autom4te.cache
/m4
/test_*
/.build*
# Ignore user defined CMake presets
CMakeUserPresets.json
# The files autogenerated by automake.
Makefile.in
aclocal.m4
configure
@@ -9,6 +26,5 @@ config.sub
depcomp
install-sh
ltmain.sh
m4/
missing
test-driver
+3
View File
@@ -0,0 +1,3 @@
[submodule "benchmarks/submatch_java/REgen"]
path = benchmarks/submatch_java/REgen
url = https://github.com/skvadrik/REgen.git
+68 -14
View File
@@ -1,8 +1,14 @@
language: cpp
# use Ubuntu 20.04 (Focal Fossa) that defaults to Python 3
dist: focal
# speed up incremental builds
cache: ccache
compiler:
- gcc
- clang
- gcc
- clang
# preinstalled packages
addons:
@@ -11,20 +17,68 @@ addons:
- bison
- python3-docutils
# in-tree and out-of-tree builds
# configurations: cmake/autotools, in-tree/out-of-tree, release/debug, etc.
env:
- BUILD_DIR=. CONFIG_DIR=.
- BUILD_DIR=.build CONFIG_DIR=..
- CMAKE=no BUILD_DIR=. CONFIG_DIR=. COMMON_FLAGS="-O2 -g"
- CMAKE=no BUILD_DIR=.build CONFIG_DIR=.. CONFIG_FLAGS="--enable-debug" COMMON_FLAGS="-O2 -g"
- CMAKE=yes BUILD_DIR=. CONFIG_DIR=. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g"
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g" SKELETON=yes
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Release
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g -fsanitize=address"
- CMAKE=yes BUILD_DIR=.build CONFIG_DIR=.. BUILD_TYPE=Debug COMMON_FLAGS="-O2 -g -fsanitize=undefined"
script:
- ./autogen.sh
- mkdir -p $BUILD_DIR && cd $BUILD_DIR
- |
$CONFIG_DIR/configure \
--prefix="$(pwd)"/re2c-install \
--enable-docs \
--enable-debug \
--enable-libs
function run_cmake() {
cmake \
-B . -S ${CONFIG_DIR} \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DCMAKE_C_FLAGS="${COMMON_FLAGS}" \
-DCMAKE_CXX_FLAGS="${COMMON_FLAGS}" \
-DCMAKE_EXE_LINKER_FLAGS="${COMMON_FLAGS}" \
-DCMAKE_SHARED_LINKER_FLAGS="${COMMON_FLAGS}" \
$@
}
function run_configure() {
${CONFIG_DIR}/configure \
${CONFIG_FLAGS} \
CFLAGS="${COMMON_FLAGS}" \
CXXFLAGS="${COMMON_FLAGS}" \
LDFLAGS="${COMMON_FLAGS}" \
$@
}
- |
if [ x${CMAKE} = "xyes" ]; then
mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
run_cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install"
else
./autogen.sh
mkdir -p ${BUILD_DIR} && cd ${BUILD_DIR}
run_configure --prefix="$(pwd)/install"
fi
- make -j$(nproc)
- make -j$(nproc) check VERBOSE=1
- make -j$(nproc) install
- make install
- |
if [ x${CMAKE} = "xyes" ]; then
run_cmake -DCMAKE_INSTALL_PREFIX="$(pwd)/install-2" \
-DRE2C_BUILD_RE2GO=on \
-DRE2C_BUILD_LIBS=on \
-DRE2C_REBUILD_DOCS=on \
-DRE2C_REBUILD_LEXERS=on \
-DRE2C_FOR_BUILD="$(pwd)/install/bin/re2c"
else
run_configure --prefix="$(pwd)/install-2" \
--enable-golang \
--enable-libs \
--enable-docs \
--enable-lexers \
RE2C_FOR_BUILD="$(pwd)/install/bin/re2c"
fi
- find ${CONFIG_DIR}/src -name '*.re' | xargs touch
- make -j$(nproc)
- |
if [ x${SKELETON} = "xyes" ]; then
./run_tests.py --skeleton
else
make -j$(nproc) check VERBOSE=1
fi
+198
View File
@@ -0,0 +1,198 @@
How to build
============
Dependencies
------------
To build re2c from a release tarball one needs only a C++ compiler and
optionally Python 3 to run the tests.
To develop re2c one also needs CMake or Autotools. Re2c can be built with either
of the two build systems, and they are both maintained and tested on CI. Other
build dependencies include Bison (to rebuild parsers), rst2man (to rebuild
documentation), Sphinx (to rebuild the website), and optionally Mingw and Wine
(to run Windows tests on Linux). A few helper scripts are written in Haskell,
but they are not essential for re2c development.
Re2c is a self-hosting lexer generator, meaning that parts of its source code
are written in re2c (namely, all the source files that have a *.re* extension).
By default re2c builds from pregenerated bootstrap files. To regenerate these
files it is necessary to configure re2c in a special way and provide a path to
an existing re2c binary (see the details below). Normally this is not necessary,
and the pregenerated files can be used as long as the *.re* files are unchanged.
Build (Autotools)
-----------------
If you are building from a release tarball, the configure script is already
there. Otherwise it is necessary to generate it:
```
$ autoreconf -i -W all
```
An in-tree build (objects are generated side by side with sources):
```
$ ./configure && make && make install
```
An out-of-tree build (objects are generated in a separate directory):
```
$ mkdir .build && cd .build && ../configure && make && make install
```
The configure script has many options (to see them all, run
`configure --help`). The options specific to re2c are the following:
* `--enable-debug`
Enable debug checks in the re2c source code. Also enables debug options.
* `--enable-golang`
Build re2go (identical to `re2c --lang go`). This is on by default.
* `--enable-lexers`
Enable regeneration of *.re* files (as opposed to using bootstrap files).
This requires setting `RE2C_FOR_BUILD` to an existing re2c executable
path.
* `--enable-docs`
Enable regeneration of documentation (requires rst2man).
* `--enable-benchmarks`
Build benchmarks (requires google benchmarks library).
* `--enable-benchmarks-regenerate`
Regenerate C code for Ragel and Kleenex benchmarks (this will download and
build Ragel and Kleenex). Re2c benchmarks are always regenerated.
* `--enable-libs`
Build the experimental libre2c library that provides POSIX
`regcomp`/`regexec`/`regfree` interface to re2c.
Cross-compile re2c for Windows (for some Mingw versions you might have to use
`-std=gnu++11` compiler option):
```
$ ./configure --host i686-w64-ming32 \
LDFLAGS="-static -static-libstdc++ -static-libgcc"
```
There is a bunch of build scripts for specialized builds with Asan, Ubsan,
GLIBCXX_DEBUG, etc. in the ``build`` subdirectory.
Build (CMake)
-------------
CMake supports different build modes, which can be further customized with
individual options. By default re2c builds with `-O2 -g` and does not set any
particular mode to allow the user complete freedom in overriding the build
options. To enable a build mode at configure phase, use
`-DCMAKE_BUILD_TYPE=<mode>` option (this works with single-config generators,
such as Makefiles or Ninja). At build phase use `--config <mode>` option.
The following modes are supported:
* `Release`
This is an optimized `-O3 -DNDEBUG` build without debug symbols, asserts
and debug checks.
* `Debug`
This is a non-optimized `-g -DRE2C_DEBUG` build with debug symbols, asserts,
and debug checks.
* `RelWithDebInfo`
This is an optimized `-O2 -g -DNDEBUG` build with debug symbols, but
without asserts and debug checks.
* `MinSizeRel`
This is an optimized for size `-Os -DNDEBUG` build without debug symbols,
asserts and debug checks.
* `Asan`
This is a non-optimized `-g -fsanitize=address` build that instruments the
code with Address Sanitizer to check for memory errors.
* `Ubsan`
This is a non-optimized `-g -fsanitize=undefined` build that instruments
the code with Undefined Behavior Sanitizer to check for undefined behavior
errors.
A simple build (objects are generated in a separate build directory):
```
$ mkdir .build && cd .build && cmake .. && cmake --build .
```
CMake supports a lot of configuration options. Here is the list of options
specific to re2c:
* `-DRE2C_BUILD_RE2GO=yes`
Build re2go executable (an alias to `re2c --lang go`). Enabled by default.
* `-DRE2C_REBUILD_LEXERS=yes`
Enable regeneration of *.re* files (as opposed to using bootstrap files).
This requires setting `-DRE2C_FOR_BUILD` to an existing re2c executable
path.
* `-DRE2C_REBUILD_DOCS=yes`
Enable regeneration of documentation (requires rst2man).
* `-DRE2C_BUILD_BENCHMARKS=yes`
Build benchmarks (requires google benchmarks library).
* `-DRE2C_REGEN_BENCHMARKS=yes`
Regenerate C code for Ragel and Kleenex benchmarks (this will download and
build Ragel and Kleenex). Re2c benchmarks are always regenerated.
* `-DRE2C_BUILD_LIBS=yes`
Build the experimental libre2c library that provides POSIX
`regcomp`/`regexec`/`regfree` interface to re2c.
Cross-compile re2c for Windows using Mingw:
```
$ cmake . -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-cross-mingw32-linux.cmake \
-DCMAKE_EXE_LINKER_FLAGS="-static -static-libstdc++ -static-libgcc" \
-DBUILD_SHARED_LIBS=no
```
There is a bunch of build scripts for specialized builds with Asan, Ubsan,
GLIBCXX_DEBUG, etc. in the ``build`` subdirectory.
Test
----
Re2c has a main test suite and a number of unit tests. Run them all:
```
$ make check
```
Run only the main test suite and watch the progress dumped on stdout:
```
$ python3 run_tests.py -j<N>
```
Run the main test suite with `--skeleton` re2c option:
```
$ python3 run_tests.py --skeleton
```
Run the test suite under Valgrind (takes some time and memory):
```
$ python3 run_tests.py --valgrind
```
Test Mingw builds with Wine:
```
$ make wtests
```
Check the distribution (works with Autotools):
```
$ make distcheck
```
Re2c provides a helper script `build/__alltest.sh` that builds and tests
various re2c build flavours with Asan, Ubsan, GLIBCXX_DEBUG, etc. There is a
couple of fuzz-testing Haskell scripts in the *fuzz* subdirectory; they are
based on the QuickCheck library and can be easily modified to fuzz-test various
aspects of re2c by comparing current re2c version against older versions or
against other regular expression libraries.
+242
View File
@@ -1,10 +1,252 @@
Changelog
=========
----
2.2x
----
2.2 (2021-08-01)
~~~~~~~~~~~~~~~~
- Added named blocks and block lists in directives.
- Added local blocks ``/*!local:re2c ... */``.
- Added in-block ``!include`` directive.
- Added in-block ``!use`` directive.
- Allowed reusable blocks without ``-r --reusable`` option.
- Allowed customizing the generated code with configurations for directives
``max:re2c``, ``maxnmatch:re2c``, ``stags:re2c``, ``mtags:re2c`` and
``types:re2c`` (see directive descriptions for details).
- Forbid arbitrary text at the end of ``max:re2c`` directive. This may break
backwards compatibility, although it is unlikely that this was used by anyone.
The change was necessary in order to allow customization of the generated code
with configurations.
- Deprecated configurations ``flags:i``, ``flags:no-debug-info`` in favour of
the global options ``-i``, ``--no-debug-info``.
- Reimplemented re2c test runner in Python (thanks to
`Serghei Iakovlev <https://github.com/sergeyklay>`_). Improved integration
with GitHub Actions.
- Changes in the experimental libre2c library: added new algorithms that
construct t-string or extract submatch on all repetitions; added TDFA
benchmark written in Java by Angelo Borsotti.
- Updated documentation.
----
2.1x
----
2.1.1 (2021-03-27)
~~~~~~~~~~~~~~~~~~
- Added missing CMakeLists.txt to release tarballs
(`#346 <https://github.com/skvadrik/re2c/issues/346>`_).
2.1 (2021-03-26)
~~~~~~~~~~~~~~~~
- Added GitHub Actions CI for Linux, macOS and Windows and fixed numerous build
issues on those platforms (thanks to
`Serghei Iakovlev <https://github.com/sergeyklay>`_).
- Added benchmarks for submatch extraction in lexer generators (ragel vs.
kleenex vs. re2c with TDFA(0), TDFA(1) or sta-DFA algorithms).
+ New Autotools (configure) options: ``--enable-benchmarks``,
``--enable-benchmarks-regenerate``
+ New CMake options: ``-DRE2C_BUILD_BENCHMARKS``, ``-DRE2C_REGEN_BENCHMARKS``
+ New `json2pgfplot.py
<https://github.com/skvadrik/re2c/blob/master/benchmarks/json2pgfplot.py>`_
script that converts benchmark results in JSON to a PDF with bar charts
- Added option ``--depfile <filename>`` to generate build dependency files
(allows to track ``/*!include:re2c*/`` dependencies in the build system).
- Added option ``--fixed-tags <none | all | toplevel>`` and improved fixed-tag
optimization to work with nested tags.
- Added lzip to the distribution tarballs.
- Added registerless-TDFA algorithm in the experimental libre2c library.
- Explicitly disallowed invalid configuration when ``-f``, ``--storable-state``
option is used, but ``YYFILL`` is disabled
(`#306 <https://github.com/skvadrik/re2c/issues/306>`_).
- Fixed bug in UTF-8 decode for 4-bytes rune
(`#307 <https://github.com/skvadrik/re2c/pull/307>`_, thanks to
`Satoshi Yasushima <https://github.com/s-yasu>`_).
- Fixed bugs in rare cases of the end-of-input rule ``$`` usage
(`277f0295 <https://github.com/skvadrik/re2c/commit/277f0295fc77a2dad3b9838e45f787319b54a25f>`_,
`68611a57 <https://github.com/skvadrik/re2c/commit/68611a57a9683c05801255b35ba6217b91391dd8>`_
and `a9d582f9 <https://github.com/skvadrik/re2c/commit/a9d582f9d2a6d123aa55f3b8b73076aae7cb5616>`_).
- Optimized ``--skeleton`` generation time.
- Renamed internal option ``--dfa`` to ``--nested-negative-tags``.
- Updated documentation for end of input handling and submatch extraction.
----
2.0x
----
2.0.3 (2020-08-22)
~~~~~~~~~~~~~~~~~~
- Fix issues when building re2c as a CMake subproject
(`#302 <https://github.com/skvadrik/re2c/pull/302>`_:
Using CMake add_subdirectory fails)
- Final corrections in the SIMPA article "RE2C: A lexer generator based on
lookahead-TDFA", https://doi.org/10.1016/j.simpa.2020.100027
2.0.2 (2020-08-08)
~~~~~~~~~~~~~~~~~~
- Enable re2go building by default.
- Package CMake files into release tarball.
2.0.1 (2020-07-29)
~~~~~~~~~~~~~~~~~~
- Updated version for CMake build system (forgotten in release 2.0).
- Added a short article about re2c for the Software Impacts journal.
2.0 (2020-07-20)
~~~~~~~~~~~~~~~~
- Added new code generation backend for Go and a new ``re2go`` program
(`#272 <https://github.com/skvadrik/re2c/issues/272>`_: Go support).
Added option ``--lang <c | go>``.
- Added CMake build system as an alternative to Autotools
(`#275 <https://github.com/skvadrik/re2c/pull/275>`_:
Add a CMake build system (thanks to ligfx),
`#244 <https://github.com/skvadrik/re2c/issues/244>`_: Switching to CMake).
- Changes in generic API:
+ Removed primitives ``YYSTAGPD`` and ``YYMTAGPD``.
+ Added primitives ``YYSHIFT``, ``YYSHIFTSTAG``, ``YYSHIFTMTAG``
that allow to express fixed tags in terms of generic API.
+ Added configurations ``re2c:api:style`` and ``re2c:api:sigil``.
+ Added named placeholders in interpolated configuration strings.
- Changes in reuse mode (``-r, --reuse`` option):
+ Do not reset API-related configurations in each `use:re2c` block
(`#291 <https://github.com/skvadrik/re2c/issues/291>`_:
Defines in rules block are not propagated to use blocks).
+ Use block-local options instead of last block options.
+ Do not accumulate options from rules/reuse blocks in whole-program options.
+ Generate non-overlapping YYFILL labels for reuse blocks.
+ Generate start label for each reuse block in storable state mode.
- Changes in start-conditions mode (``-c, --start-conditions`` option):
+ Allow to use normal (non-conditional) blocks in `-c` mode
(`#263 <https://github.com/skvadrik/re2c/issues/263>`_:
allow mixing conditional and non-conditional blocks with -c,
`#296 <https://github.com/skvadrik/re2c/issues/296>`_:
Conditions required for all lexers when using '-c' option).
+ Generate condition switch in every re2c block
(`#295 <https://github.com/skvadrik/re2c/issues/295>`_:
Condition switch generated for only one lexer per file).
- Changes in the generated labels:
+ Use ``yyeof`` label prefix instead of ``yyeofrule``.
+ Use ``yyfill`` label prefix instead of ``yyFillLabel``.
+ Decouple start label and initial label (affects label numbering).
- Removed undocumented configuration ``re2c:flags:o``, ``re2c:flags:output``.
- Changes in ``re2c:flags:t``, ``re2c:flags:type-header`` configuration:
filename is now relative to the output file directory.
- Added option ``--case-ranges`` and configuration ``re2c:flags:case-ranges``.
- Extended fixed tags optimization for the case of fixed-counter repetition.
- Fixed bugs related to EOF rule:
+ `#276 <https://github.com/skvadrik/re2c/issues/276>`_:
Example 01_fill.re in docs is broken
+ `#280 <https://github.com/skvadrik/re2c/issues/280>`_:
EOF rules with multiple blocks
+ `#284 <https://github.com/skvadrik/re2c/issues/284>`_:
mismatched YYBACKUP and YYRESTORE
(Add missing fallback states with EOF rule)
- Fixed miscellaneous bugs:
+ `#286 <https://github.com/skvadrik/re2c/issues/286>`_:
Incorrect submatch values with fixed-length trailing context.
+ `#297 <https://github.com/skvadrik/re2c/issues/297>`_:
configure error on ubuntu 18.04 / cmake 3.10
- Changed bootstrap process (require explicit configuration flags and a path to
re2c executable to regenerate the lexers).
- Added internal options ``--posix-prectable <naive | complex>``.
- Added debug option ``--dump-dfa-tree``.
- Major revision of the paper "Efficient POSIX submatch extraction on NFA".
----
1.3x
----
1.3 (2019-12-14)
~~~~~~~~~~~~~~~~
- Added option: ``--stadfa``.
- Added warning: ``-Wsentinel-in-midrule``.
- Added generic API primitives:
+ ``YYSTAGPD``
+ ``YYMTAGPD``
- Added configurations:
+ ``re2c:sentinel = 0;``
+ ``re2c:define:YYSTAGPD = "YYSTAGPD";``
+ ``re2c:define:YYMTAGPD = "YYMTAGPD";``
- Worked on reproducible builds
(`#258 <https://github.com/skvadrik/re2c/pull/258>`_:
Make the build reproducible).
----
1.2x
----
1.2.1 (2019-08-11)
~~~~~~~~~~~~~~~~~~
- Fixed bug `#253 <https://github.com/skvadrik/re2c/issues/253>`_:
re2c should install unicode_categories.re somewhere.
- Fixed bug `#254 <https://github.com/skvadrik/re2c/issues/254>`_:
Turn off re2c:eof = 0.
1.2 (2019-08-02)
~~~~~~~~~~~~~~~~
+532
View File
@@ -0,0 +1,532 @@
cmake_minimum_required(VERSION 3.12)
project(re2c VERSION 2.2 HOMEPAGE_URL "https://re2c.org/")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Re2cAutotoolsHelpers)
include(Re2cBootstrapLexer)
include(Re2cBootstrapParser)
include(Re2cBuildType)
include(Re2cGenDocs)
include(Re2cCompilerFlags)
ac_subst(PACKAGE_VERSION "${PROJECT_VERSION}")
option(RE2C_REBUILD_LEXERS "Regenerate lexers" OFF)
if(RE2C_REBUILD_LEXERS AND NOT RE2C_FOR_BUILD)
message(FATAL_ERROR "option RE2C_FOR_BUILD is required for RE2C_REBUILD_LEXERS")
endif()
option(RE2C_REBUILD_DOCS "Regenerate manpage" OFF)
if(RE2C_REBUILD_DOCS)
find_program(RST2MAN NAMES rst2man rst2man.py)
if(NOT RST2MAN)
message(FATAL_ERROR "rst2man (or rst2man.py) program is required for RE2C_REBUILD_DOCS")
endif()
# Windows does not have a native 'man' and 'sed' commands.
# Therefore, we are looking for the Cygwin versions of 'man' and 'sed'.
if (WIN32)
find_program(MAN_EXECUTABLE man)
if(NOT MAN_EXECUTABLE)
message(FATAL_ERROR "man program is required for RE2C_REBUILD_DOCS")
endif()
find_program(SED_EXECUTABLE sed)
if(NOT SED_EXECUTABLE)
message(FATAL_ERROR "sed program is required for RE2C_REBUILD_DOCS")
endif()
endif()
endif()
option(RE2C_BUILD_LIBS "Build libraries" OFF)
option(RE2C_BUILD_RE2GO "Build re2go executable (an alias for `re2c --lang go`)" ON)
option(RE2C_BUILD_BENCHMARKS "Build benchmarks" OFF)
option(RE2C_REGEN_BENCHMARKS "Regenerate C code for benchmarks" OFF)
# checks for programs
find_package(BISON)
find_package(Python3 COMPONENTS Interpreter)
# checks for C++ compiler flags
set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) # make sure object libraries work with shared libraries
# use system stdint.h if present, otherwise fallback to src/c99_stdint.h
ac_check_headers("stdint.h")
# needed for POSIX file API
ac_check_headers("sys/types.h")
ac_check_headers("sys/stat.h")
ac_check_headers("fcntl.h")
ac_check_headers("unistd.h")
# windows POSIX-like API
ac_check_headers("io.h")
# list of possible types to use in typedefs
ac_check_sizeof("char")
ac_check_sizeof("short")
ac_check_sizeof("int")
ac_check_sizeof("long")
ac_check_sizeof("long long")
ac_check_sizeof("__int64")
ac_check_sizeof("void *")
# 64-bit integer constant suffix
ac_check_sizeof("0l")
ac_check_sizeof("0ll")
ac_check_sizeof("0i8")
# docs (manpages and help)
set(re2c_manpage_source "${CMAKE_CURRENT_BINARY_DIR}/doc/manpage.rst")
set(re2c_help_source "${CMAKE_CURRENT_BINARY_DIR}/doc/help.rst")
set(re2c_manpage_bootstrap_c "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/doc/re2c.1")
set(re2c_manpage_bootstrap_go "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/doc/re2go.1")
set(re2c_help_bootstrap "${CMAKE_CURRENT_SOURCE_DIR}/bootstrap/src/msg/help.cc")
set(re2c_manpage_c "${CMAKE_CURRENT_BINARY_DIR}/doc/re2c.1")
set(re2c_manpage_go "${CMAKE_CURRENT_BINARY_DIR}/doc/re2go.1")
set(re2c_help "${CMAKE_CURRENT_BINARY_DIR}/src/msg/help.cc")
set(re2c_genhelp "${CMAKE_CURRENT_SOURCE_DIR}/build/gen_help.sh")
set(re2c_splitman "${CMAKE_CURRENT_SOURCE_DIR}/build/split_man.sh")
set(re2c_docs
"${re2c_help}"
"${re2c_manpage_c}"
"$<$<BOOL:${RE2C_BUILD_RE2GO}>:${re2c_manpage_go}>"
)
set(top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set(top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
set(PYTHON "${Python3_EXECUTABLE}")
configure_file(doc/manpage.rst.in doc/manpage.rst @ONLY)
configure_file(doc/help.rst.in doc/help.rst @ONLY)
configure_file(run_tests.py.in run_tests.py @ONLY)
set(RE2C_RUN_TESTS "${CMAKE_CURRENT_BINARY_DIR}/run_tests.py")
if(CMAKE_HOST_UNIX)
execute_process(COMMAND chmod +x "${RE2C_RUN_TESTS}")
endif()
ac_config_headers("config.h")
# Makefile.am
set(RE2C_STDLIB_DIR "${CMAKE_INSTALL_PREFIX}/share/re2c/stdlib")
add_compile_definitions(
"RE2C_STDLIB_DIR=\"${RE2C_STDLIB_DIR}\""
$<$<CONFIG:Debug>:RE2C_DEBUG>
)
include_directories(. "${CMAKE_CURRENT_BINARY_DIR}")
# Build autogenerated sources into an object library to ensure that they are
# generated once at the beginning of build (as with Automake BUILT_SOURCES).
# WARNING: custom target that depends on autogenerated sources won't do here
# as its dependencies get built multiple times, which ruins parallel builds.
add_library(re2c_objects_autogen OBJECT
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/parser.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/parser.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lex.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lex.h"
"${CMAKE_CURRENT_BINARY_DIR}/src/parse/lex_conf.cc"
"${CMAKE_CURRENT_BINARY_DIR}/src/options/parse_opts.cc"
"${re2c_docs}"
)
add_library(re2c_objects_autogen_ver_to_vernum OBJECT
"${CMAKE_CURRENT_BINARY_DIR}/src/msg/ver_to_vernum.cc"
)
set(re2c_sources
src/codegen/code_goto.cc
src/codegen/combine.cc
src/codegen/gen_bitmaps.cc
src/codegen/gen_delayed.cc
src/codegen/gen_dfa.cc
src/codegen/gen_goto.cc
src/codegen/gen_program.cc
src/codegen/gen_state.cc
src/codegen/helpers.cc
src/codegen/render.cc
src/options/opt.cc
src/options/symtab.cc
src/nfa/estimate_size.cc
src/nfa/re_to_nfa.cc
src/adfa/adfa.cc
src/debug/dump_adfa.cc
src/debug/dump_cfg.cc
src/debug/dump_dfa.cc
src/debug/dump_dfa_tree.cc
src/debug/dump_interf.cc
src/debug/dump_nfa.cc
src/cfg/cfg.cc
src/cfg/compact.cc
src/cfg/dce.cc
src/cfg/freeze.cc
src/cfg/interfere.cc
src/cfg/liveanal.cc
src/cfg/normalize.cc
src/cfg/optimize.cc
src/cfg/rename.cc
src/cfg/varalloc.cc
src/dfa/closure.cc
src/dfa/dead_rules.cc
src/dfa/determinization.cc
src/dfa/fallback_tags.cc
src/dfa/fillpoints.cc
src/dfa/find_state.cc
src/dfa/minimization.cc
src/dfa/stacmd.cc
src/dfa/tagver_table.cc
src/dfa/tcmd.cc
src/encoding/ebcdic/ebcdic_regexp.cc
src/encoding/enc.cc
src/encoding/range_suffix.cc
src/encoding/utf8/utf8_regexp.cc
src/encoding/utf8/utf8.cc
src/encoding/utf16/utf16_regexp.cc
src/encoding/utf16/utf16.cc
src/msg/msg.cc
src/msg/warn.cc
src/regexp/ast_to_re.cc
src/regexp/default_tags.cc
src/regexp/fixed_tags.cc
src/regexp/nullable.cc
src/regexp/re.cc
src/regexp/rule.cc
src/regexp/split_charset.cc
src/regexp/tag.cc
src/compile.cc
src/skeleton/control_flow.cc
src/skeleton/generate_code.cc
src/skeleton/generate_data.cc
src/skeleton/maxpath.cc
src/skeleton/skeleton.cc
src/parse/ast.cc
src/parse/input.cc
src/parse/parse.cc
src/parse/scanner.cc
src/parse/unescape.cc
src/util/file_utils.cc
src/util/s_to_n32_unsafe.cc
src/util/temp_file.cc
src/util/range.cc
src/main.cc
$<TARGET_OBJECTS:re2c_objects_autogen>
$<TARGET_OBJECTS:re2c_objects_autogen_ver_to_vernum>
)
# re2c
add_executable(re2c ${re2c_sources})
# re2go
if (RE2C_BUILD_RE2GO)
add_executable(re2go ${re2c_sources})
target_compile_definitions(re2go PUBLIC "RE2C_LANG=LANG_GO")
endif()
re2c_bootstrap_lexer("src/parse/lex.re" "src/parse/lex.cc" "src/parse/lex.h")
re2c_bootstrap_lexer("src/parse/lex_conf.re" "src/parse/lex_conf.cc")
re2c_bootstrap_lexer("src/options/parse_opts.re" "src/options/parse_opts.cc")
re2c_bootstrap_lexer("src/msg/ver_to_vernum.re" "src/msg/ver_to_vernum.cc")
re2c_bootstrap_parser("src/parse/parser.ypp" "src/parse/parser.cc" "src/parse/parser.h")
# docs
set(re2c_docs_sources
"${re2c_manpage_source}"
"doc/manual/api/interface.rst_"
"doc/manual/conditions/conditions.rst_"
"doc/manual/configurations/configurations.rst_"
"doc/manual/directives/directives.rst_"
"doc/manual/dot/dot.rst_"
"doc/manual/encodings/encodings.rst_"
"doc/manual/eof/01_sentinel.rst_"
"doc/manual/eof/02_bounds_checking.rst_"
"doc/manual/eof/03_eof_rule.rst_"
"doc/manual/eof/04_generic_api.rst_"
"doc/manual/eof/eof.rst_"
"doc/manual/fill/01_fill.rst_"
"doc/manual/fill/02_fill.rst_"
"doc/manual/fill/fill.rst_"
"doc/manual/headers/headers.rst_"
"doc/manual/includes/includes.rst_"
"doc/manual/options/debug.rst_"
"doc/manual/options/internal.rst_"
"doc/manual/options/options.rst_"
"doc/manual/regexps/regular_expressions.rst_"
"doc/manual/reuse/reuse.rst_"
"doc/manual/skeleton/skeleton.rst_"
"doc/manual/state/state.rst_"
"doc/manual/submatch/submatch_example_mtags.rst_"
"doc/manual/submatch/submatch_example_posix.rst_"
"doc/manual/submatch/submatch_example_stags.rst_"
"doc/manual/submatch/submatch_example_stags_fill.rst_"
"doc/manual/submatch/submatch.rst_"
"doc/manual/syntax/syntax.rst_"
"doc/manual/syntax/api1.rst_"
"doc/manual/syntax/api2_c.rst_"
"doc/manual/syntax/api2_go.rst_"
"doc/manual/syntax/api3.rst_"
"doc/manual/warnings/warnings_general.rst_"
"doc/manual/warnings/warnings_list.rst_"
"examples/c/01_basic.re"
"examples/c/conditions/parse_u32_conditions.re"
"examples/c/encodings/unicode_identifier.re"
"examples/c/eof/01_sentinel.re"
"examples/c/eof/02_bounds_checking.re"
"examples/c/eof/03_eof_rule.re"
"examples/c/eof/05_generic_api_eof_rule.re"
"examples/c/fill/01_fill.re"
"examples/c/fill/02_fill.re"
"examples/c/headers/header.re"
"examples/c/headers/src/lexer/lexer.h"
"examples/c/includes/include.re"
"examples/c/includes/definitions.h"
"examples/c/reuse/reuse.re"
"examples/c/reuse/usedir.re"
"examples/c/state/push.re"
"examples/c/submatch/01_stags.re"
"examples/c/submatch/01_stags_fill.re"
"examples/c/submatch/02_mtags.re"
"examples/c/submatch/03_posix.re"
"examples/go/01_basic.re"
"examples/go/conditions/parse_u32_conditions.re"
"examples/go/encodings/unicode_identifier.re"
"examples/go/eof/01_sentinel.re"
"examples/go/eof/02_bounds_checking.re"
"examples/go/eof/03_eof_rule.re"
"examples/go/eof/05_generic_api_eof_rule.re"
"examples/go/fill/01_fill.re"
"examples/go/fill/02_fill.re"
"examples/go/headers/header.re"
"examples/go/headers/src/lexer/lexer.go"
"examples/go/includes/include.re"
"examples/go/includes/definitions.go"
"examples/go/reuse/reuse.re"
"examples/go/reuse/usedir.re"
"examples/go/state/push.re"
"examples/go/submatch/01_stags.re"
"examples/go/submatch/02_mtags.re"
"examples/go/submatch/03_posix.re"
)
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_c}" "${re2c_manpage_bootstrap_c}" "c")
re2c_gen_manpage("${re2c_manpage_source}" "${re2c_manpage_go}" "${re2c_manpage_bootstrap_go}" "go")
re2c_gen_help("${re2c_help_source}" "${re2c_help}" "${re2c_help_bootstrap}")
add_custom_target(docs DEPENDS "${re2c_docs}")
# install and test targets are enabled only if re2c is the root project
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
# install
install(TARGETS re2c RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_c}" DESTINATION "share/man/man1")
if(RE2C_BUILD_RE2GO)
install(TARGETS re2go RUNTIME DESTINATION bin)
install(FILES "${re2c_manpage_go}" DESTINATION "share/man/man1")
endif()
install(FILES include/unicode_categories.re DESTINATION "${RE2C_STDLIB_DIR}")
# rebuild all re2c sources using newly built re2c
add_custom_target(bootstrap
COMMAND "${CMAKE_COMMAND}" -E remove_directory "src"
COMMAND "${CMAKE_COMMAND}" -E remove_directory "doc"
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_CURRENT_BINARY_DIR}"
)
# tests
add_custom_target(tests
DEPENDS "${RE2C_RUN_TESTS}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND "${Python3_EXECUTABLE}" "${RE2C_RUN_TESTS}"
)
add_dependencies(tests re2c)
add_custom_target(vtests
DEPENDS "${RE2C_RUN_TESTS}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND "${Python3_EXECUTABLE}" "${RE2C_RUN_TESTS}" --valgrind
)
add_dependencies(vtests re2c)
add_custom_target(wtests
DEPENDS "${RE2C_RUN_TESTS}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMAND "${Python3_EXECUTABLE}" "${RE2C_RUN_TESTS}" --wine -j1
)
add_dependencies(wtests re2c)
add_executable(re2c_test_range
src/test/range/test-impl.h
src/test/range/test.cc
src/test/range/test.h
src/util/range.cc
src/util/range.h
src/util/static_assert.h
)
add_executable(re2c_test_s_to_n32_unsafe
src/test/s_to_n32_unsafe/test.cc
src/util/s_to_n32_unsafe.cc
)
add_executable(re2c_test_ver_to_vernum
src/test/ver_to_vernum/test.cc
$<TARGET_OBJECTS:re2c_objects_autogen_ver_to_vernum>
)
add_executable(re2c_test_argsubst
src/test/argsubst/test.cc
src/codegen/helpers.cc
)
add_custom_target(check_re2c
COMMAND ./re2c_test_range
COMMAND ./re2c_test_s_to_n32_unsafe
COMMAND ./re2c_test_ver_to_vernum
COMMAND ./re2c_test_argsubst
)
add_dependencies(check_re2c
tests
re2c_test_range
re2c_test_s_to_n32_unsafe
re2c_test_ver_to_vernum
re2c_test_argsubst
)
endif()
if (RE2C_BUILD_LIBS)
# Build autogenerated sources into an object library to ensure that they are
# generated once at the beginning of build (as with Automake BUILT_SOURCES).
# WARNING: custom target that depends on autogenerated sources won't do here
# as its dependencies get built multiple times, which ruins parallel builds.
add_library(libre2c_objects_autogen OBJECT
"${CMAKE_CURRENT_BINARY_DIR}/lib/lex.cc"
"${CMAKE_CURRENT_BINARY_DIR}/lib/parse.cc"
)
re2c_bootstrap_lexer("lib/lex.re" "lib/lex.cc")
re2c_bootstrap_parser("lib/parse.ypp" "lib/parse.cc" "lib/parse.h")
add_library(test_libre2c_objects_autogen OBJECT
"${CMAKE_CURRENT_BINARY_DIR}/lib/test_helper.cc"
)
re2c_bootstrap_lexer("lib/test_helper.re" "lib/test_helper.cc")
add_library(libre2c_objects OBJECT
lib/regcomp.cc
lib/regexec.cc
lib/regexec_dfa.cc
lib/regexec_dfa_regless.cc
lib/regexec_nfa_leftmost.cc
lib/regexec_nfa_leftmost_trie.cc
lib/regexec_nfa_posix.cc
lib/regexec_nfa_posix_trie.cc
lib/regexec_nfa_posix_backward.cc
lib/regexec_nfa_posix_kuklewicz.cc
lib/regfree.cc
lib/stubs.cc
src/parse/ast.cc
src/parse/unescape.cc
src/options/opt.cc
src/options/symtab.cc
src/cfg/cfg.cc
src/cfg/compact.cc
src/cfg/dce.cc
src/cfg/freeze.cc
src/cfg/interfere.cc
src/cfg/liveanal.cc
src/cfg/normalize.cc
src/cfg/optimize.cc
src/cfg/rename.cc
src/cfg/varalloc.cc
src/dfa/closure.cc
src/debug/dump_adfa.cc
src/debug/dump_cfg.cc
src/debug/dump_dfa.cc
src/debug/dump_dfa_tree.cc
src/debug/dump_interf.cc
src/debug/dump_nfa.cc
src/dfa/dead_rules.cc
src/dfa/determinization.cc
src/dfa/fallback_tags.cc
src/dfa/fillpoints.cc
src/dfa/find_state.cc
src/dfa/minimization.cc
src/dfa/stacmd.cc
src/dfa/tagver_table.cc
src/dfa/tcmd.cc
src/nfa/estimate_size.cc
src/nfa/re_to_nfa.cc
src/encoding/enc.cc
src/encoding/range_suffix.cc
src/encoding/ebcdic/ebcdic_regexp.cc
src/encoding/utf16/utf16.cc
src/encoding/utf16/utf16_regexp.cc
src/encoding/utf8/utf8.cc
src/encoding/utf8/utf8_regexp.cc
src/msg/msg.cc
src/msg/warn.cc
src/regexp/ast_to_re.cc
src/regexp/default_tags.cc
src/regexp/fixed_tags.cc
src/regexp/nullable.cc
src/regexp/re.cc
src/regexp/rule.cc
src/regexp/split_charset.cc
src/regexp/tag.cc
src/skeleton/control_flow.cc
src/skeleton/maxpath.cc
src/skeleton/skeleton.cc
src/util/range.cc
src/util/s_to_n32_unsafe.cc
)
set(libre2c_sources
$<TARGET_OBJECTS:libre2c_objects>
$<TARGET_OBJECTS:libre2c_objects_autogen>
$<TARGET_OBJECTS:re2c_objects_autogen_ver_to_vernum>
)
# on Windows add suffix to static libs to avoid collision of .lib files with shared libs
set(RE2C_STATIC_LIB_SFX "$<$<PLATFORM_ID:Windows>:_static>")
# build static libraries
if ((NOT DEFINED BUILD_SHARED_LIBS) OR (NOT BUILD_SHARED_LIBS))
add_library(libre2c_static STATIC ${libre2c_sources})
set_target_properties(libre2c_static PROPERTIES OUTPUT_NAME "re2c${RE2C_STATIC_LIB_SFX}")
if (UNIX)
install(TARGETS libre2c_static ARCHIVE DESTINATION lib)
endif()
endif()
# build shared libraries
if ((NOT DEFINED BUILD_SHARED_LIBS) OR BUILD_SHARED_LIBS)
add_library(libre2c_shared SHARED ${libre2c_sources})
set_target_properties(libre2c_shared PROPERTIES OUTPUT_NAME "re2c")
if (UNIX)
install(TARGETS libre2c_shared LIBRARY DESTINATION lib)
endif()
endif()
# define top-level aliases to either static or shared libraries (default is static)
if (BUILD_SHARED_LIBS)
add_library(libre2c ALIAS libre2c_shared)
else()
add_library(libre2c ALIAS libre2c_static)
endif()
# libre2c test
add_executable(test_libre2c lib/test.cc)
target_link_libraries(test_libre2c libre2c)
target_link_libraries(test_libre2c test_libre2c_objects_autogen)
add_custom_target(check_libre2c
COMMAND ./test_libre2c
)
if(RE2C_BUILD_BENCHMARKS)
add_subdirectory(benchmarks/submatch_nfa)
add_subdirectory(benchmarks/submatch_dfa_jit)
add_subdirectory(benchmarks/submatch_java)
endif()
else()
# empty check target
add_custom_target(check_libre2c)
endif()
if(RE2C_BUILD_BENCHMARKS)
add_subdirectory(benchmarks/submatch_dfa_aot)
endif()
# only add check target if toplevel project
if (CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
add_custom_target(check)
add_dependencies(check check_re2c check_libre2c)
endif()
+471
View File
@@ -0,0 +1,471 @@
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 1
},
"configurePresets": [
{
"name": "default-full-configuration",
"hidden": true,
"installDir": "${sourceDir}/install-2",
"cacheVariables": {
"RE2C_BUILD_RE2GO": true,
"RE2C_BUILD_LIBS": true,
"RE2C_REBUILD_LEXERS": true,
"RE2C_REBUILD_DOCS": true,
"RE2C_FOR_BUILD": "${sourceDir}/install/bin/re2c"
}
},
{
"name": "linux-config-base",
"hidden": true,
"generator": "Unix Makefiles",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "gcc",
"CMAKE_CXX_COMPILER": "g++"
}
},
{
"name": "linux-gcc-ubsan-ootree-fast",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Ubsan",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "linux-gcc-ubsan-ootree-full",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-ubsan-ootree-fast"]
},
{
"name": "linux-gcc-asan-ootree-fast",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Asan",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "linux-gcc-asan-ootree-full",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-asan-ootree-fast"]
},
{
"name": "linux-gcc-debug-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "linux-gcc-debug-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-debug-ootree-skeleton-fast"]
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-fast",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}",
"installDir": "${sourceDir}/install",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2 -m32",
"CMAKE_CXX_FLAGS": "-O2 -m32",
"CMAKE_EXE_LINKER_FLAGS": "-m32",
"CMAKE_SHARED_LINKER_FLAGS": "-m32",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-full",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-debug-intree-m32-skeleton-fast"]
},
{
"name": "linux-gcc-release-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (fast)",
"inherits": "linux-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "linux-gcc-release-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "linux-gcc-release-ootree-skeleton-fast"]
},
{
"name": "macos-config-base",
"hidden": true,
"generator": "Unix Makefiles",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "clang",
"CMAKE_CXX_COMPILER": "clang++"
}
},
{
"name": "macos-clang-debug-ootree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (fast)",
"inherits": "macos-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "macos-clang-debug-ootree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "macos-clang-debug-ootree-skeleton-fast"]
},
{
"name": "macos-clang-debug-intree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (fast)",
"inherits": "macos-config-base",
"binaryDir": "${sourceDir}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-O2",
"CMAKE_CXX_FLAGS": "-O2",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "macos-clang-debug-intree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (full)",
"inherits": ["default-full-configuration", "macos-clang-debug-intree-skeleton-fast"]
},
{
"name": "macos-clang-release-ootree-skeleton-fast",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (fast)",
"inherits": "macos-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "macos-clang-release-ootree-skeleton-full",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (full)",
"inherits": ["default-full-configuration", "macos-clang-release-ootree-skeleton-fast"]
},
{
"name": "windows-config-base",
"hidden": true,
"generator": "Visual Studio 16 2019",
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
},
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl"
}
},
{
"name": "windows-msvc-debug-ootree-fast",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (fast)",
"inherits": "windows-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "windows-msvc-debug-ootree-full",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (full)",
"inherits": ["default-full-configuration", "windows-msvc-debug-ootree-fast"],
"cacheVariables": {
"RE2C_REBUILD_DOCS": false
}
},
{
"name": "windows-msvc-debug-intree-fast",
"displayName": "Windows x86_64: MSVC / Debug / In tree (fast)",
"inherits": "windows-config-base",
"binaryDir": "${sourceDir}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "windows-msvc-debug-intree-full",
"displayName": "Windows x86_64: MSVC / Debug / In tree (full)",
"inherits": ["default-full-configuration", "windows-msvc-debug-intree-fast"],
"cacheVariables": {
"RE2C_REBUILD_DOCS": false
}
},
{
"name": "windows-msvc-release-ootree-fast",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (fast)",
"inherits": "windows-config-base",
"binaryDir": "${sourceDir}/.build/${presetName}",
"installDir": "${sourceDir}/install",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"RE2C_BUILD_RE2GO": false
}
},
{
"name": "windows-msvc-release-ootree-full",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (full)",
"inherits": ["default-full-configuration", "windows-msvc-release-ootree-fast"],
"cacheVariables": {
"RE2C_REBUILD_DOCS": false
}
}
],
"buildPresets": [
{
"name": "linux-build-base",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
}
},
{
"name": "linux-gcc-ubsan-ootree-fast",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (fast)",
"configurePreset": "linux-gcc-ubsan-ootree-fast",
"inherits": "linux-build-base",
"configuration": "Ubsan"
},
{
"name": "linux-gcc-ubsan-ootree-full",
"displayName": "Linux x86_64: GCC / Ubsan / Out of tree (full)",
"configurePreset": "linux-gcc-ubsan-ootree-full",
"inherits": "linux-build-base",
"configuration": "Ubsan"
},
{
"name": "linux-gcc-asan-ootree-fast",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (fast)",
"configurePreset": "linux-gcc-asan-ootree-fast",
"inherits": "linux-build-base",
"configuration": "Asan"
},
{
"name": "linux-gcc-asan-ootree-full",
"displayName": "Linux x86_64: GCC / Asan / Out of tree (full)",
"configurePreset": "linux-gcc-asan-ootree-full",
"inherits": "linux-build-base",
"configuration": "Asan"
},
{
"name": "linux-gcc-debug-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (fast)",
"configurePreset": "linux-gcc-debug-ootree-skeleton-fast",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-debug-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Debug / Skeleton / Out of tree (full)",
"configurePreset": "linux-gcc-debug-ootree-skeleton-full",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-fast",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (fast)",
"configurePreset": "linux-gcc-debug-intree-m32-skeleton-fast",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-debug-intree-m32-skeleton-full",
"displayName": "Linux x86: GCC / Debug / Skeleton / In tree (full)",
"configurePreset": "linux-gcc-debug-intree-m32-skeleton-full",
"inherits": "linux-build-base",
"configuration": "Debug"
},
{
"name": "linux-gcc-release-ootree-skeleton-fast",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (fast)",
"configurePreset": "linux-gcc-release-ootree-skeleton-fast",
"inherits": "linux-build-base",
"configuration": "Release"
},
{
"name": "linux-gcc-release-ootree-skeleton-full",
"displayName": "Linux x86_64: GCC / Release / Skeleton / Out of tree (full)",
"configurePreset": "linux-gcc-release-ootree-skeleton-full",
"inherits": "linux-build-base",
"configuration": "Release"
},
{
"name": "macos-build-base",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Darwin"
}
},
{
"name": "macos-clang-debug-ootree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (fast)",
"configurePreset": "macos-clang-debug-ootree-skeleton-fast",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-debug-ootree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / Out of tree (full)",
"configurePreset": "macos-clang-debug-ootree-skeleton-full",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-debug-intree-skeleton-fast",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (fast)",
"configurePreset": "macos-clang-debug-intree-skeleton-fast",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-debug-intree-skeleton-full",
"displayName": "macOS x86_64: Clang / Debug / Skeleton / In tree (full)",
"configurePreset": "macos-clang-debug-intree-skeleton-full",
"inherits": "macos-build-base",
"configuration": "Debug"
},
{
"name": "macos-clang-release-ootree-skeleton-fast",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (fast)",
"configurePreset": "macos-clang-release-ootree-skeleton-fast",
"inherits": "macos-build-base",
"configuration": "Release"
},
{
"name": "macos-clang-release-ootree-skeleton-full",
"displayName": "macOS x86_64: CLang / Release / Skeleton / Out of tree (full)",
"configurePreset": "macos-clang-release-ootree-skeleton-full",
"inherits": "macos-build-base",
"configuration": "Release"
},
{
"name": "windows-build-base",
"hidden": true,
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "windows-msvc-debug-ootree-fast",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (fast)",
"configurePreset": "windows-msvc-debug-ootree-fast",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-debug-ootree-full",
"displayName": "Windows x86_64: MSVC / Debug / Out of tree (full)",
"configurePreset": "windows-msvc-debug-ootree-full",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-debug-intree-fast",
"displayName": "Windows x86_64: MSVC / Debug / In tree (fast)",
"configurePreset": "windows-msvc-debug-intree-fast",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-debug-intree-full",
"displayName": "Windows x86_64: MSVC / Debug / In tree (full)",
"configurePreset": "windows-msvc-debug-intree-full",
"inherits": "windows-build-base",
"configuration": "Debug"
},
{
"name": "windows-msvc-release-ootree-fast",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (fast)",
"configurePreset": "windows-msvc-release-ootree-fast",
"inherits": "windows-build-base",
"configuration": "Release"
},
{
"name": "windows-msvc-release-ootree-full",
"displayName": "Windows x86_64: MSVC / Release / Out of tree (full)",
"configurePreset": "windows-msvc-release-ootree-full",
"inherits": "windows-build-base",
"configuration": "Release"
}
]
}
+52
View File
@@ -0,0 +1,52 @@
[re2c][re2c] was written in 1993 by Peter Bumbulis. Since then it has been
maintained and developed by multiple volunteers. Contributions are welcome,
please have a look at the guidelines below.
## Contributions
The preferred form of a contribution is a pull request on GitHub. Patches sent
by email are also fine (but less convenient). Discussion in
[GitHub issues][issues] is welcome. Email threads are also fine (but less
convenient).
## Language guidelines
re2c is written in C++. The project uses a conservative language subset (for
portability reasons the currently used standard is C++98). The code should stay
simple and avoid complex object hierarchies and excessive use of template
metaprogramming. It should allow the reader to concentrate on the underlying
algorithms, without the language getting in the way.
The line length limit is 90 characters, indentation is 4 spaces, and the
indentation style is more or less K&R (egyptian braces).
## Updating bootstrap files
For changes that affect lexers (`.re` files), it is necessary to regenerate the
corresponding bootstrap files. This can be done by reconfiguring and
rebuilding re2c with options `--enable-lexers` (Autotools) or
`-DRE2C_REBUILD_LEXERS=ON` (CMake). `RE2C_FOR_BUILD` should be defined as a
path to an already existing re2c executable that will be used to regenerate
the lexers.
For changes that affect parser (`.ypp` files), it is necessary to regenerate
bootstrap parser files. This happens automatically if bison is installed.
For changes that update documentation, it is necessary to rebuild the
bootstrap manpages by reconfiguring and rebuilding re2c with options
`--enable-docs` (Autotools) or `-DRE2C_REBUILD_DOCS=ON` (CMake).
Please do not commit trivial updates to the bootstrap files, such as changes of
the generator version or generation date.
## Commit messages
The headline should use present tense and start with a capital letter. Commit
messages should be as descriptive as possible and avoid uncertain terms like
"fix", "refactoring", "code cleanup" and so on. Long commit messages with
explanations, examples and test instructions are welcome.
Unrelated changes should be split into multiple commits.
[re2c]: http://re2c.org/
[issues]: https://github.com/skvadrik/re2c/issues
+169 -74
View File
@@ -1,27 +1,28 @@
# flags
# do *not* add CXXFLAGS here, add them in configure.ac
SUBDIRS = .
# stdlib directory
stdlibdir = $(datadir)/re2c/stdlib
# do not add compiler options/warnings here, add them in configure.ac
AM_CXXFLAGS = $(CXXFLAGSDEFAULT)
AM_CXXFLAGS += -DRE2C_STDLIB_DIR='"$(stdlibdir)/"'
if DEBUG
AM_CXXFLAGS += -DRE2C_DEBUG
endif
RE2CFLAGS = -br -W
RE2CFLAGS = -br -W -Wno-match-empty-string
# binary
bin_PROGRAMS = re2c
noinst_PROGRAMS =
RE2C = re2c$(EXEEXT)
# sources
re2c_HDR = \
src/codegen/bitmap.h \
src/codegen/emit.h \
src/codegen/go.h \
src/codegen/input_api.h \
src/codegen/label.h \
src/codegen/output.h \
src/codegen/print.h \
src/constants.h \
src/codegen/code.h \
src/codegen/helpers.h \
src/options/opt.h \
src/adfa/action.h \
src/options/symtab.h \
src/adfa/adfa.h \
src/cfg/cfg.h \
src/dfa/closure_leftmost.h \
@@ -29,6 +30,7 @@ re2c_HDR = \
src/dfa/determinization.h \
src/dfa/dfa.h \
src/dfa/posix_precedence.h \
src/dfa/stacmd.h \
src/dfa/tag_history.h \
src/dfa/tagver_table.h \
src/dfa/tcmd.h \
@@ -46,11 +48,11 @@ re2c_HDR = \
src/msg/msg.h \
src/msg/ver_to_vernum.h \
src/msg/warn.h \
src/regexp/empty_class_policy.h \
src/regexp/re.h \
src/regexp/rule.h \
src/regexp/tag.h \
src/compile.h \
src/skeleton/mtag_trie.h \
src/skeleton/path.h \
src/skeleton/skeleton.h \
src/parse/ast.h \
@@ -62,11 +64,10 @@ re2c_HDR = \
src/util/allocate.h \
src/util/attribute.h \
src/util/c99_stdint.h \
src/util/counter.h \
src/util/file_utils.h \
src/util/fixed_allocator.h \
src/util/forbid_copy.h \
src/util/free_list.h \
src/util/get_dir.h \
src/util/hash32.h \
src/util/local_increment.h \
src/util/lookup.h \
@@ -78,28 +79,27 @@ re2c_HDR = \
src/util/string_utils.h \
src/util/temp_file.h \
src/util/u32lim.h \
src/util/uniq_vector.h \
src/util/wrap_iter.h
src/util/uniq_vector.h
re2c_SRC = \
src/codegen/bitmap.cc \
src/codegen/emit_action.cc \
src/codegen/emit_dfa.cc \
src/codegen/label.cc \
src/codegen/go_construct.cc \
src/codegen/go_destruct.cc \
src/codegen/go_emit.cc \
src/codegen/go_used_labels.cc \
src/codegen/input_api.cc \
src/codegen/output.cc \
src/codegen/print.cc \
src/codegen/code_goto.cc \
src/codegen/combine.cc \
src/codegen/gen_bitmaps.cc \
src/codegen/gen_delayed.cc \
src/codegen/gen_dfa.cc \
src/codegen/gen_goto.cc \
src/codegen/gen_program.cc \
src/codegen/gen_state.cc \
src/codegen/helpers.cc \
src/codegen/render.cc \
src/options/opt.cc \
src/options/symtab.cc \
src/nfa/estimate_size.cc \
src/nfa/re_to_nfa.cc \
src/adfa/adfa.cc \
src/adfa/prepare.cc \
src/debug/dump_adfa.cc \
src/debug/dump_cfg.cc \
src/debug/dump_dfa.cc \
src/debug/dump_dfa_tree.cc \
src/debug/dump_interf.cc \
src/debug/dump_nfa.cc \
src/cfg/cfg.cc \
@@ -119,6 +119,7 @@ re2c_SRC = \
src/dfa/fillpoints.cc \
src/dfa/find_state.cc \
src/dfa/minimization.cc \
src/dfa/stacmd.cc \
src/dfa/tagver_table.cc \
src/dfa/tcmd.cc \
src/encoding/ebcdic/ebcdic_regexp.cc \
@@ -134,6 +135,7 @@ re2c_SRC = \
src/regexp/default_tags.cc \
src/regexp/fixed_tags.cc \
src/regexp/nullable.cc \
src/regexp/re.cc \
src/regexp/rule.cc \
src/regexp/split_charset.cc \
src/regexp/tag.cc \
@@ -145,11 +147,10 @@ re2c_SRC = \
src/skeleton/skeleton.cc \
src/parse/ast.cc \
src/parse/input.cc \
src/parse/normalize.cc \
src/parse/parse.cc \
src/parse/scanner.cc \
src/parse/unescape.cc \
src/parse/validate.cc \
src/util/get_dir.cc \
src/util/file_utils.cc \
src/util/s_to_n32_unsafe.cc \
src/util/temp_file.cc \
src/util/range.cc
@@ -185,10 +186,12 @@ BUILT_SOURCES = $(re2c_GEN_SRC)
# bootstrap sources
re2c_BOOT_PARSER = bootstrap/src/parse/parser.cc
re2c_BOOT_PARSER_HDR = bootstrap/src/parse/parser.h
re2c_BOOT_DOC = bootstrap/doc/re2c.1
re2c_BOOT_DOC_C = bootstrap/doc/re2c.1
re2c_BOOT_DOC_GO = bootstrap/doc/re2go.1
re2c_BOOT_HELP = bootstrap/src/msg/help.cc
re2c_BOOT = \
$(re2c_BOOT_DOC) \
$(re2c_BOOT_DOC_C) \
$(re2c_BOOT_DOC_GO) \
$(re2c_BOOT_HELP) \
$(re2c_BOOT_PARSER) \
$(re2c_BOOT_PARSER_HDR) \
@@ -212,88 +215,143 @@ re2c_CUSTOM = \
# docs
re2c_SRC_DOC = doc/manpage.rst
re2c_SRC_DOC_EXT = \
doc/manual/api/api.rst_ \
doc/manual/api/interface.rst_ \
doc/manual/conditions/conditions.rst_ \
doc/manual/configurations/configurations.rst_ \
doc/manual/directives/directives.rst_ \
doc/manual/dot/dot.rst_ \
doc/manual/encodings/encodings.rst_ \
doc/manual/eof/01_sentinel.re \
doc/manual/eof/01_sentinel.rst_ \
doc/manual/eof/02_bounds_checking.re \
doc/manual/eof/02_bounds_checking.rst_ \
doc/manual/eof/03_eof_rule.re \
doc/manual/eof/03_eof_rule.rst_ \
doc/manual/eof/04_generic_api.re \
doc/manual/eof/04_generic_api.rst_ \
doc/manual/eof/eof.rst_ \
doc/manual/fill/01_fill.re \
doc/manual/fill/01_fill.rst_ \
doc/manual/fill/02_fill.re \
doc/manual/fill/02_fill.rst_ \
doc/manual/fill/fill.rst_ \
doc/manual/fill/input.txt \
doc/manual/headers/headers.rst_ \
doc/manual/includes/includes.rst_ \
doc/manual/options/options_list.rst_ \
doc/manual/options/debug.rst_ \
doc/manual/options/internal.rst_ \
doc/manual/options/options.rst_ \
doc/manual/regexps/regular_expressions.rst_ \
doc/manual/reuse/reuse.re \
doc/manual/reuse/reuse.rst_ \
doc/manual/skeleton/skeleton.rst_ \
doc/manual/state/push.re \
doc/manual/state/state.rst_ \
doc/manual/submatch/mtags.re \
doc/manual/submatch/posix.re \
doc/manual/submatch/stags.re \
doc/manual/submatch/submatch_example_mtags.rst_ \
doc/manual/submatch/submatch_example_posix.rst_ \
doc/manual/submatch/submatch_example_stags.rst_ \
doc/manual/submatch/submatch_example_stags_fill.rst_ \
doc/manual/submatch/submatch.rst_ \
doc/manual/syntax/syntax.rst_ \
doc/manual/syntax/api1.rst_ \
doc/manual/syntax/api2_c.rst_ \
doc/manual/syntax/api2_go.rst_ \
doc/manual/syntax/api3.rst_ \
doc/manual/warnings/warnings_general.rst_ \
doc/manual/warnings/warnings_list.rst_
doc/manual/warnings/warnings_list.rst_ \
examples/c/01_basic.re \
examples/c/conditions/parse_u32_conditions.re \
examples/c/encodings/unicode_identifier.re \
examples/c/eof/01_sentinel.re \
examples/c/eof/02_bounds_checking.re \
examples/c/eof/03_eof_rule.re \
examples/c/eof/05_generic_api_eof_rule.re \
examples/c/fill/01_fill.re \
examples/c/fill/02_fill.re \
examples/c/headers/header.re \
examples/c/headers/src/lexer/lexer.h \
examples/c/includes/include.re \
examples/c/includes/definitions.h \
examples/c/reuse/reuse.re \
examples/c/reuse/usedir.re \
examples/c/state/push.re \
examples/c/submatch/01_stags.re \
examples/c/submatch/01_stags_fill.re \
examples/c/submatch/02_mtags.re \
examples/c/submatch/03_posix.re \
examples/go/01_basic.re \
examples/go/conditions/parse_u32_conditions.re \
examples/go/encodings/unicode_identifier.re \
examples/go/eof/01_sentinel.re \
examples/go/eof/02_bounds_checking.re \
examples/go/eof/03_eof_rule.re \
examples/go/eof/05_generic_api_eof_rule.re \
examples/go/fill/01_fill.re \
examples/go/fill/02_fill.re \
examples/go/headers/header.re \
examples/go/headers/src/lexer/lexer.go \
examples/go/includes/include.re \
examples/go/includes/definitions.go \
examples/go/reuse/reuse.re \
examples/go/reuse/usedir.re \
examples/go/state/push.re \
examples/go/submatch/01_stags.re \
examples/go/submatch/02_mtags.re \
examples/go/submatch/03_posix.re
DOC = doc/re2c.1
man_MANS = $(DOC)
DOC_C = doc/re2c.1
DOCS = $(DOC_C)
if WITH_GOLANG
DOC_GO = doc/re2go.1
DOCS += $(DOC_GO)
endif
man_MANS = $(DOCS)
# include files (stdlib)
dist_stdlib_DATA = include/unicode_categories.re
CMAKEFILES := \
CMakeLists.txt \
cmake
EXTRA_DIST = \
$(re2c_BOOT) \
$(re2c_CUSTOM) \
$(re2c_SRC_DOC_EXT) \
$(CMAKEFILES) \
CHANGELOG \
LICENSE \
NO_WARRANTY \
README.md \
autogen.sh \
genhelp.sh \
build \
examples \
include \
test
CLEANFILES = \
$(re2c_GEN) \
$(DOC)
$(DOCS)
if REBUILD_LEXERS
# generate lexer and update bootstrap files
.re.cc:
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN) if test -x $(RE2C); \
$(AM_V_GEN)if test -x $(RE2C_FOR_BUILD); \
then \
$(top_builddir)/$(RE2C) $(RE2CFLAGS) -o $@ $< && \
$(RE2C_FOR_BUILD) $(RE2CFLAGS) -o $@ $< && \
cp $(@:cc=[ch]*) $(top_srcdir)/bootstrap/$(@D); \
else \
cp $(top_srcdir)/bootstrap/$(@:cc=*) $(@D); \
echo "RE2C is not an executable file" && exit 1 ; \
fi
else
# copy bootstrap files
.re.cc:
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/bootstrap/$(@:cc=*) $(@D)
$(AM_V_at)echo "Reconfigure with --enable-lexers to regenerate $@"
endif
# cannot update bootstrap with distcheck (it makes srcdir readonly),
# so we update bootstrap only on incremental build (if re2c binary exists)
.ypp.cc:
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN) if test $(BISON) = "no"; \
$(AM_V_GEN)if test $(BISON) = "no"; \
then \
cp $(top_srcdir)/bootstrap/$(@:cc=*) $(@D); \
else \
$(BISON) --output=$@ --defines=$(@:cc=h) $< && \
if test -x $(RE2C); then \
if test -x $(top_builddir)/re2c$(EXEEXT); then \
cp $@ $(@:cc=h) $(top_srcdir)/bootstrap/$(@D); \
fi; \
fi
@@ -309,22 +367,42 @@ bootstrap: all
.PHONY: docs
if REBUILD_DOCS
docs: $(DOC) $(re2c_GEN_HELP)
$(DOC): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT)
docs: $(DOCS) $(re2c_GEN_HELP)
GENHELP = $(top_srcdir)/build/gen_help.sh
SPLITMAN = $(top_srcdir)/build/split_man.sh
# generate manpage for C
$(DOC_C): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN)
$(AM_V_at)$(MKDIR_P) $(@D)
$(RST2MAN) $(top_builddir)/$(re2c_SRC_DOC) > $@
$(AM_V_GEN)cp $@ $(top_srcdir)/$(re2c_BOOT_DOC)
$(re2c_GEN_HELP): $(re2c_CUSTOM_HELP)
$(AM_V_GEN)$(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).c c \
&& $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).c > $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_DOC_C) \
&& rm $(top_builddir)/$(re2c_SRC_DOC).c
# generate manpage for Go
$(DOC_GO): $(re2c_SRC_DOC) $(re2c_SRC_DOC_EXT) $(SPLITMAN)
$(AM_V_at)$(MKDIR_P) $(@D)
$(RST2MAN) $(top_builddir)/$(re2c_CUSTOM_HELP) > $@.1
$(top_srcdir)/genhelp.sh $@.1 $@
$(AM_V_GEN)cp $@ $(top_srcdir)/$(re2c_BOOT_HELP)
$(AM_V_GEN)$(SPLITMAN) $(top_builddir)/$(re2c_SRC_DOC) $(top_builddir)/$(re2c_SRC_DOC).go go \
&& $(RST2MAN) --tab-width=4 $(top_builddir)/$(re2c_SRC_DOC).go > $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_DOC_GO) \
&& rm $(top_builddir)/$(re2c_SRC_DOC).go
# generate help
$(re2c_GEN_HELP): $(re2c_CUSTOM_HELP) $(GENHELP)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)$(RST2MAN) $(top_builddir)/$(re2c_CUSTOM_HELP) > $@.1 \
&& $(GENHELP) $@.1 $@ \
&& cp $@ $(top_srcdir)/$(re2c_BOOT_HELP) \
&& rm $@.1
else
docs: $(DOC) $(re2c_GEN_HELP)
$(AM_V_at)echo "Reconfigure to rebuild docs: ./configure --enable-docs"
$(DOC): $(re2c_BOOT_DOC)
docs: $(DOCS) $(re2c_GEN_HELP)
$(AM_V_at)echo "Reconfigure with --enable-docs to rebuild docs"
# copy bootstrap manpage for C
$(DOC_C): $(re2c_BOOT_DOC_C)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/$(re2c_BOOT_DOC) $@
$(AM_V_GEN)cp $(top_srcdir)/$(re2c_BOOT_DOC_C) $@
# copy bootstrap manpage for Go
$(DOC_GO): $(re2c_BOOT_DOC_GO)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/$(re2c_BOOT_DOC_GO) $@
# copy bootstrap help
$(re2c_GEN_HELP): $(re2c_BOOT_HELP)
$(AM_V_at)$(MKDIR_P) $(@D)
$(AM_V_GEN)cp $(top_srcdir)/$(re2c_BOOT_HELP) $@
@@ -333,7 +411,7 @@ endif
all-local: docs $(re2c_BOOT_PARSER)
# tests
re2c_TESTSUITE = run_tests.sh
re2c_TESTSUITE = run_tests.py
.PHONY: tests
tests: all $(re2c_TESTSUITE)
$(top_builddir)/$(re2c_TESTSUITE)
@@ -360,19 +438,36 @@ re2c_test_ver_to_vernum_SOURCES = \
src/test/ver_to_vernum/test.cc \
$(re2c_GEN_VER_TO_VERNUM)
re2c_test_argsubst_SOURCES = \
src/test/argsubst/test.cc
check_PROGRAMS = \
re2c_test_range \
re2c_test_s_to_n32_unsafe \
re2c_test_ver_to_vernum
re2c_test_ver_to_vernum \
re2c_test_argsubst
TESTS = \
$(re2c_TESTSUITE) \
$(check_PROGRAMS)
# libraries go here (in included .am files)
# benchmarks
if WITH_BENCHMARKS
SUBDIRS += benchmarks/submatch_dfa_aot
EXTRA_DIST += benchmarks/submatch_dfa_aot
endif
# libre2c
if WITH_LIBS
ACLOCAL_AMFLAGS = -I m4
lib_LTLIBRARIES =
include $(top_srcdir)/Makefile.lib.am
endif
# re2go
if WITH_GOLANG
bin_PROGRAMS += re2go
re2go_CXXFLAGS = $(AM_CXXFLAGS) -DRE2C_LANG=LANG_GO
re2go_SOURCES = $(re2c_SOURCES)
nodist_re2go_SOURCES = $(nodist_re2c_SOURCES)
endif
+32 -20
View File
@@ -7,17 +7,14 @@ libre2c_la_LDFLAGS = -module -no-undefined
libre2c_la_HDR = \
lib/lex.h \
lib/regcomp_dfa_regless.h \
lib/regex.h \
lib/regex_impl.h \
src/codegen/bitmap.h \
src/codegen/emit.h \
src/codegen/go.h \
src/codegen/input_api.h \
src/codegen/label.h \
src/codegen/output.h \
src/codegen/print.h \
lib/regoff_trie.h \
src/constants.h \
src/codegen/code.h \
src/options/opt.h \
src/adfa/action.h \
src/options/symtab.h \
src/adfa/adfa.h \
src/cfg/cfg.h \
src/dfa/closure_leftmost.h \
@@ -25,6 +22,7 @@ libre2c_la_HDR = \
src/dfa/determinization.h \
src/dfa/dfa.h \
src/dfa/posix_precedence.h \
src/dfa/stacmd.h \
src/dfa/tag_history.h \
src/dfa/tagver_table.h \
src/dfa/tcmd.h \
@@ -42,7 +40,6 @@ libre2c_la_HDR = \
src/msg/msg.h \
src/msg/ver_to_vernum.h \
src/msg/warn.h \
src/regexp/empty_class_policy.h \
src/regexp/re.h \
src/regexp/rule.h \
src/regexp/tag.h \
@@ -59,10 +56,9 @@ libre2c_la_HDR = \
src/util/allocate.h \
src/util/attribute.h \
src/util/c99_stdint.h \
src/util/counter.h \
src/util/file_utils.h \
src/util/forbid_copy.h \
src/util/free_list.h \
src/util/get_dir.h \
src/util/hash32.h \
src/util/local_increment.h \
src/util/lookup.h \
@@ -73,13 +69,13 @@ libre2c_la_HDR = \
src/util/static_assert.h \
src/util/string_utils.h \
src/util/u32lim.h \
src/util/uniq_vector.h \
src/util/wrap_iter.h
src/util/uniq_vector.h
libre2c_la_SRC = \
lib/regcomp.cc \
lib/regexec.cc \
lib/regexec_dfa.cc \
lib/regexec_dfa_regless.cc \
lib/regexec_nfa_leftmost.cc \
lib/regexec_nfa_leftmost_trie.cc \
lib/regexec_nfa_posix.cc \
@@ -91,6 +87,7 @@ libre2c_la_SRC = \
src/parse/ast.cc \
src/parse/unescape.cc \
src/options/opt.cc \
src/options/symtab.cc \
src/cfg/cfg.cc \
src/cfg/compact.cc \
src/cfg/dce.cc \
@@ -105,6 +102,7 @@ libre2c_la_SRC = \
src/debug/dump_adfa.cc \
src/debug/dump_cfg.cc \
src/debug/dump_dfa.cc \
src/debug/dump_dfa_tree.cc \
src/debug/dump_interf.cc \
src/debug/dump_nfa.cc \
src/dfa/dead_rules.cc \
@@ -113,6 +111,7 @@ libre2c_la_SRC = \
src/dfa/fillpoints.cc \
src/dfa/find_state.cc \
src/dfa/minimization.cc \
src/dfa/stacmd.cc \
src/dfa/tagver_table.cc \
src/dfa/tcmd.cc \
src/nfa/estimate_size.cc \
@@ -130,6 +129,7 @@ libre2c_la_SRC = \
src/regexp/default_tags.cc \
src/regexp/fixed_tags.cc \
src/regexp/nullable.cc \
src/regexp/re.cc \
src/regexp/rule.cc \
src/regexp/split_charset.cc \
src/regexp/tag.cc \
@@ -146,11 +146,13 @@ libre2c_la_SOURCES = \
libre2c_la_CUSTOM = \
lib/lex.re \
lib/parse.ypp \
lib/test_helper.re \
src/msg/ver_to_vernum.re
libre2c_la_GEN_SRC = \
lib/lex.cc \
lib/parse.cc \
lib/test_helper.cc \
src/msg/ver_to_vernum.cc
libre2c_la_GEN_HDR = \
lib/parse.h
@@ -165,6 +167,7 @@ libre2c_la_BOOTSTRAP = \
bootstrap/lib/parse.cc \
bootstrap/lib/parse.h \
bootstrap/lib/lex.cc \
bootstrap/lib/test_helper.cc \
bootstrap/src/msg/ver_to_vernum.cc
nodist_libre2c_la_SOURCES = $(libre2c_la_GEN)
@@ -178,13 +181,22 @@ CLEANFILES += $(libre2c_la_GEN)
# lexer depends on bison-generated header
lib/lex.cc: lib/parse.cc
test_libre2c_SOURCES = lib/test.cc
# tests
test_libre2c_SOURCES = \
lib/test.cc \
lib/test_helper.h \
lib/test_helper.cc
test_libre2c_LDADD = libre2c.la
check_PROGRAMS += test_libre2c
bench_libre2c_SOURCES = lib/bench.cc
bench_libre2c_CXXFLAGS = $(AM_CXXFLAGS) -std=c++11
bench_libre2c_LDFLAGS = $(LDFLAGS_RE2)
bench_libre2c_LDADD = libre2c.la
noinst_PROGRAMS += bench_libre2c
# benchmarks
if WITH_BENCHMARKS
SUBDIRS += benchmarks/submatch_nfa
SUBDIRS += benchmarks/submatch_dfa_jit
EXTRA_DIST += benchmarks/submatch_nfa
EXTRA_DIST += benchmarks/submatch_dfa_jit
if WITH_JAVA
SUBDIRS += benchmarks/submatch_java
EXTRA_DIST += benchmarks/submatch_java
endif # WITH_JAVA
endif # WITH_BENCHMARKS
+26 -24
View File
@@ -1,7 +1,7 @@
DESCRIPTION
-----------
re2c is a free and open-source lexer generator for C and C++.
re2c is a free and open-source lexer generator for C, C++ and Go.
Its main goal is generating fast lexers: at least as fast as their reasonably
optimized hand-coded counterparts. Instead of using traditional table-driven
@@ -19,7 +19,7 @@ code and adapt the generated lexer to any particular environment.
DOCUMENTATION
-------------
Official re2c website is [re2c.org](http://re2c.org).
Official re2c website is [re2c.org](http://re2c.org). It has a lot of examples.
DOWNLOAD
@@ -36,41 +36,43 @@ $ git clone https://git.code.sf.net/p/re2c/code-git
Github is the main repo, sourceforge is a mirror and can be slightly outdated.
CONTRIBUTING
------------
re2c is an Open Source, community-driven project. See
[CONTRIBUTING.md](https://github.com/skvadrik/re2c/blob/master/CONTRIBUTING.md) for
details about contributions to this repository.
BUILD
-----
The simplest possible way to build re2c is this:
```
$ ./configure [--prefix=<prefix>]
$ make
$ make install
```
See the [official documantation](http://re2c.org/install/install.html) for full details on more sophisticated build types.
If you want to build from git, you will first need to generate autotools files:
```
$ ./autogen.sh
```
See BUILD.md or the [online docs](https://re2c.org/build/build.html) for
instructions how to build re2c.
MAILING LISTS
-------------
FEEDBACK
--------
Bugtracker:
- https://github.com/skvadrik/re2c/issues
Mailing lists:
- re2c-general@lists.sourceforge.net
- re2c-devel@lists.sourceforge.net
IRC channels:
- irc.oftc.net/#re2c
- irc.libera.chat/#re2c
You are welcome to ask for help or share your thoughts and ideas.
BUGS
----
Please report any bugs and send feature requests to https://github.com/skvadrik/re2c/issues.
AUTHORS
-------
Re2c was originally written by Peter Bumbulis <peter@csg.uwaterloo.ca>.
Since then many people contributed to the project.
Current maintainers are Ulya Trofimovich <skvadrik@gmail.com> and Dan Nuffer <nuffer@users.sourceforge.net>.
Since then many people contributed to the project. The current maintainer is
Ulya Trofimovich <skvadrik@gmail.com>.
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
builddir=__build_lsan
rm -rf $builddir
mkdir $builddir
cd $builddir
../configure \
--enable-debug \
--enable-libs \
CXXFLAGS="-fsanitize=leak" \
LDFLAGS="-fsanitize=leak" \
&& make -j$(nproc)
cd ..
-26
View File
@@ -1,26 +0,0 @@
#!/bin/bash
set -e
if [ $# -ne 1 ]
then
echo "usage: ./distcheck.sh <builddir>"
exit 1
fi
builddir="$1"
autoreconf -i -W all
# try to be portable on various MAKEs
for make_prog in make bmake
do
rm -rf $builddir
mkdir $builddir
cd $builddir
# 'make' implies 'make docs'; running both in parallel may cause data races
# configure without --enable-debug, this is the release binary
../configure --enable-docs --enable-libs \
&& $make_prog bootstrap -j$(nproc) \
&& $make_prog distcheck -j$(nproc)
cd ..
done
+1
View File
@@ -1,4 +1,5 @@
#!/bin/sh
git clean -fX
mkdir -p m4
autoreconf -i -W all
+146
View File
@@ -0,0 +1,146 @@
#include <string.h>
#include "benchmarks/common/common.h"
#include "lib/regex.h"
#ifdef HAVE_RE2_RE2_H
#include "re2/re2.h"
#endif
static void add_counters(benchmark::State &state, const alg_t &,
const bench_t &bench, int captures)
{
size_t bytes = 0;
for (const char **s = bench.strings; *s; ++s) {
bytes += strlen(*s);
}
state.counters["captures"] = double(captures);
state.counters["regsize"] = double(strlen(bench.regexp));
}
void bench_regcomp_re2c(benchmark::State& state, const alg_t &alg, const bench_t &bench)
{
int err = 0;
size_t nmatch = 0;
for (auto _ : state) {
regex_t re;
err = regcomp(&re, bench.regexp, alg.flags);
nmatch = re.re_nsub;
regfree(&re);
}
if (err) {
state.SkipWithError("regcomp failed");
}
add_counters(state, alg, bench, int(nmatch) - 1);
}
void bench_regexec_re2c(benchmark::State& state, const alg_t &alg, const bench_t &bench)
{
regex_t re;
int err = regcomp(&re, bench.regexp, alg.flags);
if (err) {
state.SkipWithError("regcomp failed");
}
const bool with_hist = alg.flags & REG_SUBHIST;
const size_t nmatch = re.re_nsub;
regmatch_t *pmatch = with_hist ? NULL : new regmatch_t[nmatch];
// Do not move condition inside of the loop to avoid overhead.
if (with_hist) {
for (auto _ : state) {
for (const char **strings = bench.strings; *strings; ++strings) {
subhistory_t *h = regparse(&re, *strings, nmatch);
err |= h ? 0 : 1;
regfreesub(h);
}
}
} else {
for (auto _ : state) {
for (const char **strings = bench.strings; *strings; ++strings) {
err |= regexec(&re, *strings, nmatch, pmatch, 0);
}
}
}
if (err) {
state.SkipWithError("regexec failed");
}
add_counters(state, alg, bench, int(nmatch) - 1);
delete[] pmatch;
regfree(&re);
}
#ifdef HAVE_RE2_RE2_H
void bench_regcomp_re2(benchmark::State &state, const alg_t &alg, const bench_t &bench)
{
bool ok = true;
int argc = 0;
for (auto _ : state) {
RE2 re(bench.regexp, RE2::POSIX);
ok = re.ok();
argc = re.NumberOfCapturingGroups();
}
if (!ok) {
state.SkipWithError("regcomp failed");
}
add_counters(state, alg, bench, argc);
}
void bench_regexec_re2(benchmark::State &state, const alg_t &alg, const bench_t &bench)
{
RE2 re(bench.regexp, RE2::POSIX);
if (!re.ok()) {
state.SkipWithError("regcomp failed");
}
const int argc = re.NumberOfCapturingGroups();
RE2::Arg *args = new RE2::Arg[argc];
RE2::Arg **argps = new RE2::Arg*[argc];
std::string *submatch = new std::string[argc];
for (int i = 0; i < argc; ++i) {
args[i] = &submatch[i];
argps[i] = &args[i];
}
bool ok = true;
for (auto _ : state) {
for (const char **strings = bench.strings; *strings; ++strings) {
ok = ok && RE2::FullMatchN(*strings, re, argps, argc);
}
}
if (!ok) {
state.SkipWithError("regexec failed");
}
add_counters(state, alg, bench, argc);
delete[] submatch;
delete[] argps;
delete[] args;
}
#else
void bench_regcomp_re2(benchmark::State &, const alg_t &, const bench_t &) {}
void bench_regexec_re2(benchmark::State &, const alg_t &, const bench_t &) {}
#endif
void bench_regcomp_t::operator()(benchmark::State &state, const alg_t &alg,
const bench_t &bench) const {
alg.engine == ENGINE_RE2C
? bench_regcomp_re2c(state, alg, bench)
: bench_regcomp_re2(state, alg, bench);
}
void bench_regexec_t::operator()(benchmark::State &state, const alg_t &alg,
const bench_t &bench) const {
alg.engine == ENGINE_RE2C
? bench_regexec_re2c(state, alg, bench)
: bench_regexec_re2(state, alg, bench);
}
+137
View File
@@ -0,0 +1,137 @@
#ifndef _RE2C_BENCHMRKS_COMMON_COMMON_
#define _RE2C_BENCHMRKS_COMMON_COMMON_
#include <benchmark/benchmark.h>
#include <string>
#include <vector>
#include "src/util/c99_stdint.h"
enum engine_t {
ENGINE_RE2C,
ENGINE_RE2
};
struct alg_t {
const char *name;
engine_t engine;
int flags;
};
struct bench_t {
const char *name;
const char *regexp;
const char **strings;
int not_flags;
};
// Need to define benchmarks as functors for benchmark::RegisterBenchmark.
struct bench_regcomp_t {
void operator()(benchmark::State&, const alg_t&, const bench_t&) const;
};
struct bench_regexec_t {
void operator()(benchmark::State&, const alg_t&, const bench_t&) const;
};
// RFC URI and HTTP
#define CRLF "[\\n]"
#define OCT "([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5])"
#define IPV4 "(" OCT "[.]" OCT "[.]" OCT "[.]" OCT ")"
#define H16 "[0-9a-fA-F]{1,4}"
#define LS32 "(" H16 ":" H16 "|" IPV4 ")"
#define IPV6 "((" H16 ":){6}" LS32 \
"|" "::(" H16 ":){5}" LS32 \
"|(" H16 ")?::(" H16 ":){4}" LS32 \
"|((" H16 ":){0,1}" H16 ")?::(" H16 ":){3}" LS32 \
"|((" H16 ":){0,2}" H16 ")?::(" H16 ":){2}" LS32 \
"|((" H16 ":){0,3}" H16 ")?::" H16 ":" LS32 \
"|((" H16 ":){0,4}" H16 ")?::" LS32 \
"|((" H16 ":){0,5}" H16 ")?::" H16 \
"|((" H16 ":){0,6}" H16 ")?::)"
#define IPVFUTURE "(v[0-9a-fA-F]+[.][-0-9a-zA-Z._~!$&'()*+,;=:]+)"
#define IPLITERAL "([[](" IPV6 "|" IPVFUTURE ")[\\]])"
#define REGNAME "(([-0-9a-zA-Z._~!$&'()*+,;=]|%[0-9a-fA-F]{2})*)"
#define HOST "(" IPLITERAL "|" IPV4 "|" REGNAME ")"
#define PORT "(:[0-9]*)?"
#define USERINFO "(([-a-zA-Z0-9._~!$&'()*+,;=:]|%[0-9a-fA-F]{2})*@)?"
#define SCHEME "([a-zA-Z][a-zA-Z0-9+.-]*):"
#define QUERY "([?]([-a-zA-Z0-9._~!$&'()*+,;=:@/?]|%[0-9a-fA-F]{2})*)?"
#define FRAGMENT "([#]([-a-zA-Z0-9._~!$&'()*+,;=:@/?]|%[0-9a-fA-F]{2})*)?"
#define PCHAR "([-0-9a-zA-Z._~!$&'()*+,;=:@]|%[0-9a-fA-F]{2})"
#define PATH_ABEMPTY "(/" PCHAR "*)*"
#define PATH_ABSOLUTE "/(" PCHAR "+(/" PCHAR "*)*)?"
#define PATH_ROOTLESS PCHAR "+(/" PCHAR "*)*"
#define PATH_EMPTY "([/]?)"
#define AUTHORITY "(" USERINFO HOST PORT ")"
#define HIER_PART "(//" AUTHORITY PATH_ABEMPTY "|" PATH_ABSOLUTE "|" PATH_ROOTLESS "|" PATH_EMPTY ")"
#define URI SCHEME HIER_PART QUERY FRAGMENT
#define ABSOLUTE_URI SCHEME HIER_PART QUERY
#define ORIGIN_FROM PATH_ABEMPTY QUERY
#define REQUEST_TARGET "(" AUTHORITY "|" ABSOLUTE_URI "|" ORIGIN_FROM "|([*]))"
#define METHOD "([-!#$%&'*+.^_`|~0-9a-zA-Z]+)"
#define HTTP_VERSION "(HTTP/[0-9][.][0-9])"
#define STATUS_CODE "([0-9]{3})"
#define REASON_PHRASE "([ \\t \\x1f-\\x7e\\x80-\\xff]*)"
#define REQUEST_LINE METHOD "[ ]" REQUEST_TARGET "[ ]" HTTP_VERSION CRLF
#define STATUS_LINE HTTP_VERSION "[ ]" STATUS_CODE "[ ]" REASON_PHRASE CRLF
#define FIELD_NAME "([-!#$%&'*+.^_`|~0-9a-zA-Z]+)"
#define FIELD_VCHAR "[\\x1f-\\x7e\\x80-\\xff]"
#define FIELD_CONTENT "(" FIELD_VCHAR "([ \\t]+" FIELD_VCHAR")?)"
#define FIELD_VALUE "(" FIELD_CONTENT "|" CRLF "[ \\t]+)*"
#define HEADER_FIELD "(" FIELD_NAME ":[ \\t]*" FIELD_VALUE "[ \\t]*)"
#define MESSAGE_HEAD "(" REQUEST_LINE "|" STATUS_LINE ")" "(" HEADER_FIELD CRLF ")*"
// simplified URI and HTTP
#define CHAR2 "[-._~%!$&'()*+,;=a-zA-Z0-9]"
#define SCHEME2 "([-+.a-zA-Z0-9]+):"
#define USERINFO2 "((" CHAR2 "|[:])+@)?"
#define HOST2 "((" CHAR2 "|[:[\\]])+)"
#define PORT2 "(:[0-9]*)?"
#define AUTHORITY2 USERINFO2 HOST2 PORT2
#define PATH2 "((" CHAR2 "|[:@/])*)"
#define QUERY2 "([?](" CHAR2 "|[:@?/])*)?"
#define FRAGMENT2 "([#](" CHAR2 "|[:@?/])*)?"
#define URI2 SCHEME2 "(//" AUTHORITY2 ")?" PATH2 QUERY2 FRAGMENT2
#define ABSOLUTE_URI2 SCHEME2 "(//" AUTHORITY2 PORT2 ")?" PATH2 QUERY2
#define ORIGIN_FROM2 "/" PATH2 QUERY2
#define REQUEST_TARGET2 "(" AUTHORITY2 "|" ABSOLUTE_URI2 "|" ORIGIN_FROM2 "|[*])"
#define HTTP_VERSION2 "(HTTP/[0-9][.][0-9])"
#define METHOD2 "([-._~%!$&'*+#^`|a-zA-Z0-9]+)"
#define REQUEST_LINE2 "(" METHOD2 "[ ]" REQUEST_TARGET2 "[ ]" HTTP_VERSION2 CRLF ")"
#define STATUS_LINE2 "(" HTTP_VERSION2 "[ ]([0-9]{3})[ ]([\\t \\x1f-\\x7e\\x80-\\xff]*)" CRLF ")"
#define HEADER_FIELD2 "([-._~%!$&'*+#^`|a-zA-Z0-9]+:[\\x1f-\\x7e\\x80-\\xff \\t\\n]*)"
#define MESSAGE_HEAD2 "(" REQUEST_LINE2 "|" STATUS_LINE2 ")" "(" HEADER_FIELD2 CRLF ")*"
// simplified IPv6
#define IPV62 "(((" H16 ":){0,7}" H16 ")?(::)?((" H16 ":){0,7}" H16 ")?)"
// simplified IPv4
#define IPV42 "([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})"
// date
#define DATE "(Mon|Tue|Wed|Thu|Fri|Sat|Sun)" \
"[ ]+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)" \
"[ ]+([0-9]{2})" \
"[ ]+([0-9]{4})" \
"[ ]+([0-9]{2}):([0-5][0-9]):[0-5][0-9](-[0-5][0-9])?(:[0-5][0-9])?" \
"[ ]+(([A-Z]{3})([+-]([0-5][0-9]):([0-5][0-9]))?)"
// simplified date
#define DATE2 "([a-zA-Z]+)[ ]+([a-zA-Z]+)[ ]+([0-9]+)[ ]+([0-9]+)[ ]+([0-9:-]+)[ ]+([A-Z0-9+-]+)"
// Gentoo package atom
#define PACKAGE_STR "([a-zA-Z0-9_+-]+)"
#define PACKAGE_NUM "([0-9]+)"
#define PACKAGE_VER "(" PACKAGE_NUM "([.]" PACKAGE_NUM ")*)"
#define PACKAGE_SFX1 "([a-z])?"
#define PACKAGE_SFX2 "((alpha|beta|pre|rc|p)" PACKAGE_NUM "?)"
#define PACKAGE_REV "(-r" PACKAGE_NUM ")?"
#define PACKAGE_ATOM PACKAGE_STR "/" PACKAGE_STR "-" PACKAGE_VER PACKAGE_SFX1 "(_" PACKAGE_SFX2 ")*" PACKAGE_REV
// simplified Gentoo package atom
#define PACKAGE_STR2 "([a-zA-Z0-9_/+-]+)"
#define PACKAGE_VER2 "([0-9.a-z_]+)"
#define PACKAGE_ATOM2 PACKAGE_STR2 "-" PACKAGE_VER2 PACKAGE_REV
#endif // _RE2C_BENCHMRKS_COMMON_COMMON_
File diff suppressed because it is too large Load Diff
+15
View File
@@ -0,0 +1,15 @@
#ifndef _RE2C_BENCHMRKS_COMMON_STRINGS_DATE_
#define _RE2C_BENCHMRKS_COMMON_STRINGS_DATE_
static const char *date_strings[] = {
"Mon Jan 01 2019 00:24:00 GMT",
"Tue Feb 02 2018 01:24:00 GMT",
"Wed Mar 03 2017 02:24:00 GMT",
"Thu Apr 04 2016 03:24:00 GMT",
"Fri May 05 2015 04:24:00 GMT",
"Sat Jun 06 2014 05:24:00 GMT",
"Sun Jul 07 2013 06:24:00 GMT",
NULL
};
#endif // _RE2C_BENCHMRKS_COMMON_STRINGS_DATE_
+305
View File
@@ -0,0 +1,305 @@
#ifndef _RE2C_BENCHMRKS_COMMON_STRINGS_HTTP_
#define _RE2C_BENCHMRKS_COMMON_STRINGS_HTTP_
static const char *http_strings[] = {
"HTTP/5.9 430 1wSXfgruktPZfhxm\n"
"X-Forwarded-For: client1, proxy1, proxy2\n"
"WWW-Authenticate: Basic\n"
"Connection: keep-alive\n"
"x-wap-profile: http://wap.samsungmobile.com/uaprof/SGH-I777.xml\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5\n"
"Cache-Control: max-age=3600\n"
"X-Att-Deviceid: GT-P7320/P7320XXLPG\n"
"Accept-Charset: utf-8\n"
"Max-Forwards: 10\n"
"Access-Control-Allow-Origin: *\n"
"P3P: CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"\n"
,
"HTTP/9.9 858 13rxsOgH\n"
"If-None-Match: \"737060cd8c284d8af7ad3082f209582d\"\n"
"X-Frame-Options: deny\n"
"Access-Control-Allow-Origin: *\n"
"Connection: keep-alive\n"
"Retry-After: 120\n"
"ETag: \"737060cd8c284d8af7ad3082f209582d\"\n"
"Content-Range: bytes 21010-47021/47022\n"
"Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"X-UA-Compatible: IE=edge\n"
"Content-Location: /index.htm\n"
"X-UA-Compatible: Chrome=1\n"
"Content-Language: da\n"
"Accept: text/plain\n"
"Host: en.wikipedia.org:8080\n"
"Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT\n"
"X-HTTP-Method-Override: DELETE\n"
"Warning: 199 Miscellaneous warning\n"
"Accept-Charset: utf-8\n"
"Content-Location: /index.htm\n"
"Content-Range: bytes 21010-47021/47022\n"
"Retry-After: 120\n"
,
"PATCH * HTTP/4.7\n"
"Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT\n"
"Content-Type: text/html; charset=utf-8\n"
"Proxy-Connection: keep-alive\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"X-Att-Deviceid: GT-P7320/P7320XXLPG\n"
"X-Forwarded-Host: en.wikipedia.org:8080\n"
,
"HTTP/0.9 510 ZvGc2\n"
"X-WebKit-CSP: default-src 'self'\n"
"Content-Location: /index.htm\n"
"X-UA-Compatible: Chrome=1\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"X-Forwarded-Host: en.wikipedia.org\n"
"Public-Key-Pins: max-age=2592000; pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\";\n"
"Pragma: no-cache\n"
"Content-Location: /index.htm\n"
"Retry-After: Fri, 07 Nov 2014 23:59:59 GMT\n"
"Refresh: 5; url=http://www.w3.org/pub/WWW/People.html\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n"
"Connection: Upgrade\n"
"Content-Length: 51\n"
"Status: 200 OK\n"
"Strict-Transport-Security: max-age=16070400; includeSubDomains\n"
"Max-Forwards: 10\n"
"Age: 12\n"
"Alt-Svc: http/1.1=\"http2.example.com:8001\"; ma=7200\n"
"X-Att-Deviceid: GT-P7320/P7320XXLPG\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"X-WebKit-CSP: default-src 'self'\n"
"Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket\n"
"If-Range: \"737060cd8c284d8af7ad3082f209582d\"\n"
,
"HTTP/3.5 110 Aoq7A3pMGQq mgWvAz3GgU2Vlb\n"
"X-UIDH: ...\n"
"X-WebKit-CSP: default-src 'self'\n"
"If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT\n"
"From: user@example.com\n"
"Refresh: 5; url=http://www.w3.org/pub/WWW/People.html\n"
"Tk: ?\n"
"Connection: keep-alive\n"
"Origin: http://www.example-social-network.com\n"
"X-UIDH: ...\n"
"Accept-Charset: utf-8\n"
"Content-Type: application/x-www-form-urlencoded\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"DNT: 1 (Do Not Track Enabled)\n"
"Content-Encoding: gzip\n"
"If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT\n"
"Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n"
"Accept: text/plain\n"
,
"HTTP/3.6 975 SX UZSJdUJbVnFDeyLMzdyVb\n"
"X-Forwarded-Host: en.wikipedia.org\n"
"Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1\n"
"Expect: 100-continue\n"
"Content-Encoding: gzip\n"
"Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43\n"
"Content-Length: 348\n"
"Upgrade-Insecure-Requests: 1\n"
"Accept-Patch: text/example;charset=utf-8\n"
"Pragma: no-cache\n"
"Vary: *\n"
,
"HTTP/0.3 764 tfEoJrK 2p1F2Ao7OGUTxW\n"
"Connection: close\n"
"Referer: http://en.wikipedia.org/wiki/Main_Page\n"
"X-Content-Duration: 42.666\n"
"X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"Cache-Control: no-cache\n"
"Status: 200 OK\n"
"Access-Control-Allow-Origin: *\n"
,
"HTTP/9.7 828 9AvNbuZbvGKrCMzbUHOHwhQ4h\n"
"X-Content-Duration: 42.666\n"
"Trailer: Max-Forwards\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"Content-Type: text/html; charset=utf-8\n"
"Forwarded: for=192.0.2.43, for=198.51.100.17\n"
"If-Range: \"737060cd8c284d8af7ad3082f209582d\"\n"
"Pragma: no-cache\n"
"Accept-Language: en-US\n"
"Host: en.wikipedia.org:8080\n"
"If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT\n"
"Content-Encoding: gzip\n"
"Range: bytes=500-999\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"Proxy-Authenticate: Basic\n"
"X-XSS-Protection: 1; mode=block\n"
"Allow: GET, HEAD\n"
"Connection: Upgrade\n"
"Retry-After: 120\n"
"X-UIDH: ...\n"
"Content-Type: text/html; charset=utf-8\n"
"Pragma: no-cache\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"Strict-Transport-Security: max-age=16070400; includeSubDomains\n"
"X-Frame-Options: deny\n"
"X-Forwarded-For: client1, proxy1, proxy2\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"WWW-Authenticate: Basic\n"
"Tk: ?\n"
"X-Content-Type-Options: nosniff\n"
"Accept-Language: en-US\n"
,
"HTTP/6.1 785 qED83aUkhrTKg7W3iQta4\n"
"Origin: http://www.example-social-network.com\n"
"x-wap-profile: http://wap.samsungmobile.com/uaprof/SGH-I777.xml\n"
"Connection: Upgrade\n"
"Vary: Accept-Language\n"
"Content-Disposition: attachment; filename=\"fname.ext\"\n"
"Warning: 199 Miscellaneous warning\n"
"Warning: 199 Miscellaneous warning\n"
"X-Forwarded-For: client1, proxy1, proxy2\n"
"Strict-Transport-Security: max-age=16070400; includeSubDomains\n"
"Link: </feed>; rel=\"alternate\"\n"
"Pragma: no-cache\n"
"X-Powered-By: PHP/5.4.0\n"
"Vary: Accept-Language\n"
"Accept: text/plain\n"
"Pragma: no-cache\n"
"Vary: Accept-Language\n"
"x-wap-profile: http://wap.samsungmobile.com/uaprof/SGH-I777.xml\n"
"Upgrade-Insecure-Requests: 1\n"
"X-Att-Deviceid: GT-P7320/P7320XXLPG\n"
"Tk: ?\n"
"Content-Location: /index.htm\n"
"User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0\n"
"X-XSS-Protection: 1; mode=block\n"
"Content-Disposition: attachment; filename=\"fname.ext\"\n"
,
"PUT mdwishunysbgnqpk:uqfKE@154.41.44.150:8226 HTTP/7.1\n"
"Content-Type: application/x-www-form-urlencoded\n"
"From: user@example.com\n"
"Cache-Control: no-cache\n"
"Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket\n"
"DNT: 1 (Do Not Track Enabled)\n"
"Public-Key-Pins: max-age=2592000; pin-sha256=\"E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=\";\n"
"Vary: Accept-Language\n"
"Accept: text/plain\n"
"Server: Apache/2.4.1 (Unix)\n"
"X-UIDH: ...\n"
"Cache-Control: no-cache\n"
"Tk: ?\n"
"Max-Forwards: 10\n"
"X-UA-Compatible: IE=edge\n"
"Max-Forwards: 10\n"
"Proxy-Authenticate: Basic\n"
"X-Forwarded-Proto: https\n"
"X-Content-Type-Options: nosniff\n"
"From: user@example.com\n"
"P3P: CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"\n"
"X-WebKit-CSP: default-src 'self'\n"
"X-Content-Duration: 42.666\n"
"TE: trailers, deflate\n"
"Forwarded: for=192.0.2.43, for=198.51.100.17\n"
"Connection: keep-alive\n"
"Expires: Thu, 01 Dec 1994 16:00:00 GMT\n"
"Date: Tue, 15 Nov 1994 08:12:31 GMT\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"Tk: ?\n"
,
"HTTP/7.3 997 DRQt ANhTIi\n"
"Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ==\n"
"Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"If-Range: \"737060cd8c284d8af7ad3082f209582d\"\n"
"Location: http://www.w3.org/pub/WWW/People.html\n"
"Content-Length: 51\n"
"Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43\n"
"Alt-Svc: http/1.1=\"http2.example.com:8001\"; ma=7200\n"
"X-Content-Duration: 42.666\n"
"X-UIDH: ...\n"
"Content-Language: da\n"
"X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql\n"
"Host: en.wikipedia.org:8080\n"
"Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1\n"
"Range: bytes=500-999\n"
"Strict-Transport-Security: max-age=16070400; includeSubDomains\n"
"Accept-Charset: utf-8\n"
"Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT\n"
,
"HTTP/3.6 160 hE\n"
"P3P: CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"\n"
"X-Powered-By: PHP/5.4.0\n"
"Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1\n"
"Strict-Transport-Security: max-age=16070400; includeSubDomains\n"
"X-Frame-Options: deny\n"
"X-Requested-With: XMLHttpRequest\n"
"X-Powered-By: PHP/5.4.0\n"
"Retry-After: 120\n"
"User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0\n"
"X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql\n"
"Content-Type: text/html; charset=utf-8\n"
"x-wap-profile: http://wap.samsungmobile.com/uaprof/SGH-I777.xml\n"
"P3P: CP=\"This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info.\"\n"
"Accept-Language: en-US\n"
"Via: 1.0 fred, 1.1 example.com (Apache/1.1)\n"
"Pragma: no-cache\n"
"Content-Type: application/x-www-form-urlencoded\n"
"X-Requested-With: XMLHttpRequest\n"
"TE: trailers, deflate\n"
"If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT\n"
"Expect: 100-continue\n"
"Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1\n"
"Vary: *\n"
"X-Forwarded-Host: en.wikipedia.org\n"
"Host: en.wikipedia.org:8080\n"
"X-HTTP-Method-Override: DELETE\n"
"If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT\n"
,
"HTTP/6.2 328 pNN5oXYb1EMAiYawAbGE4rvjBbQ\n"
"Allow: GET, HEAD\n"
"Server: Apache/2.4.1 (Unix)\n"
"Retry-After: Fri, 07 Nov 2014 23:59:59 GMT\n"
"Cache-Control: max-age=3600\n"
"X-Content-Type-Options: nosniff\n"
"Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket\n"
"Cache-Control: no-cache\n"
,
"GET https://249.225.169.119/qmpvnqskjdsgffmsqlwvrtckpjtx/xnaszgbskztlups/wuftfvlrw/nxkpghvpjanyvdok/hxbkqjlxjdklws/onecmivzmyrwznwantuqtpz/baetoveozlpg/dgmebtggvxowkmgpyzrakffcznrzte/odbpmrrlyvzerirapn/ihkcubbsihtvenhfpnvpqf HTTP/9.1\n"
"If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT\n"
"Age: 12\n"
"X-WebKit-CSP: default-src 'self'\n"
"Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1\n"
"If-Range: \"737060cd8c284d8af7ad3082f209582d\"\n"
"TE: trailers, deflate\n"
"X-Content-Type-Options: nosniff\n"
"Accept-Language: en-US\n"
"Proxy-Connection: keep-alive\n"
"Status: 200 OK\n"
"Alt-Svc: http/1.1=\"http2.example.com:8001\"; ma=7200\n"
"Upgrade-Insecure-Requests: 1\n"
"Expect: 100-continue\n"
,
"HTTP/3.5 316 Bw05n9Cca\n"
"Pragma: no-cache\n"
,
"TRACE /kkyixdxiqyprpbwrqxrqmcz/kcepeaxtpiilfqacenwr/gkgruemrmvfeggastznmmaswf/zeysudldmbvmanstxpzsf/tdzor/jra/soygcoxezeuceiqybnsyzkrrsg/crny/jihmzdrvanvepaophpflwgpaluk/psnbrz HTTP/4.6\n"
"ETag: \"737060cd8c284d8af7ad3082f209582d\"\n"
"Proxy-Authenticate: Basic\n"
"Link: </feed>; rel=\"alternate\"\n"
"X-Forwarded-Proto: https\n"
"Front-End-Https: on\n"
"ETag: \"737060cd8c284d8af7ad3082f209582d\"\n"
"Host: en.wikipedia.org\n"
"X-Forwarded-Host: en.wikipedia.org:8080\n"
,
"HTTP/4.6 894 o4rjEil qL1gexedFU\tmKuGl8J\n"
"Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket\n"
"Date: Tue, 15 Nov 1994 08:12:31 GMT\n"
"X-XSS-Protection: 1; mode=block\n"
"Accept-Charset: utf-8\n"
"Allow: GET, HEAD\n"
"Age: 12345\n"
,
NULL
};
#endif // _RE2C_BENCHMRKS_COMMON_STRINGS_HTTP_
+13
View File
@@ -0,0 +1,13 @@
#ifndef _RE2C_BENCHMRKS_COMMON_STRINGS_IPV4_
#define _RE2C_BENCHMRKS_COMMON_STRINGS_IPV4_
static const char *ipv4_strings[] = {
"127.0.0.1",
"192.168.1.200",
"255.255.255.255",
"8.8.8.8",
"240.147.163.34",
NULL
};
#endif // _RE2C_BENCHMRKS_COMMON_STRINGS_IPV4_
+45
View File
@@ -0,0 +1,45 @@
#ifndef _RE2C_BENCHMRKS_COMMON_STRINGS_IPV6_
#define _RE2C_BENCHMRKS_COMMON_STRINGS_IPV6_
static const char *ipv6_strings[] = {
"fee2:586:10aa:fd03:37f:76ee:bed7:880",
"::fee2:586:fd03:37f:76ee:bed7:880",
"fee2::586:fd03:37f:76ee:bed7:880",
"fee2:586::fd03:37f:76ee:bed7:880",
"fee2:586:fd03::37f:76ee:bed7:880",
"fee2:586:fd03:37f::76ee:bed7:880",
"fee2:586:fd03:37f:76ee::bed7:880",
"fee2:586:fd03:37f:76ee:bed7::880",
"fee2:586:fd03:37f:76ee:bed7:880::",
"::586:fd03:37f:76ee:bed7:880",
"fee2::fd03:37f:76ee:bed7:880",
"fee2:fd03::37f:76ee:bed7:880",
"fee2:fd03:37f::76ee:bed7:880",
"fee2:fd03:37f:76ee::bed7:880",
"fee2:fd03:37f:76ee:bed7::880",
"fee2:fd03:37f:76ee:bed7:880::",
"::fd03:37f:76ee:bed7:880",
"fd03::37f:76ee:bed7:880",
"fd03:37f::76ee:bed7:880",
"fd03:37f:76ee::bed7:880",
"fd03:37f:76ee:bed7::880",
"fd03:fd03:37f:76ee:bed7::",
"::37f:76ee:bed7:880",
"fd03::76ee:bed7:880",
"fd03:37f::bed7:880",
"fd03:37f:76ee::880",
"fd03:37f:76ee:bed7::",
"::76ee:bed7:880",
"fd03::bed7:880",
"fd03:37f::880",
"fd03:37f:76ee::",
"::bed7:880",
"fd03::880",
"fd03:37f::",
"::bed7",
"fd03::",
"::",
NULL
};
#endif // _RE2C_BENCHMRKS_COMMON_STRINGS_IPV6_
+62
View File
@@ -0,0 +1,62 @@
#ifndef _RE2C_BENCHMRKS_COMMON_STRINGS_URI_
#define _RE2C_BENCHMRKS_COMMON_STRINGS_URI_
static const char *uri_strings[] = {
"http://240.147.163.34:2124/z/dibws/hkwfcdsvlghmmyd/ltiyxrfuam?fshxiix3zNzrBJNnuLDXnOruEmp4fX",
"http://yaad:60JmJOVECyQMmk@20.58.145.111:1700/gdnch/srdsabqbxp/nwsncxyawglw/bjojaxe",
"http://219.93.85.100:5179/q/y/pcraybhzqolbfrqummaly/chdgkbcqgdqzybvskovgwtn/gytxjczlwmfituesbikdimffr/xvqrmwufaaeqiufvkzvzqlvtape/nhrcdxivypkxcfb/qikdlrjrwkcrkdzjywwvuqvyjols/oonotquaxombhciqc/krpjzyvdmplsbdjpiyvwhpizvy?bjtsUNF2phdTxCYrtPLQH",
"ftp://vkfdbkyout.vfityckrzf.hsupobmbdg.juqncag.fxxi/eetvlflxtlmsccmifigfyfd/fqtdkczpvpvgn/ocfmanarai/pkrlrmnbarhxooirwau/qwtnjzkvwqrxeljnx/oknwgdxopk/palvzdkjuoiabytkar/efnzeqavdsxg/elmbmvkputgdkrspnasyxun/ctrahnuygpwncqqetwoelslynb?TNXVr7cKVbjo8KmKHSeGFFyVTb#7A66EXDTVm29hhLlp2uHyY59V2",
"file://rdahgrkzbo.iuzvfirjie.akfapgcaqu.gbeeb.wldnmxhghz/vdkvgcaunevwmvpotnt/fyifntckwqrwkimrlzicebcvqbter/aaqtkymaxovfowwrij/nghjhjimjsr/yxijmlsuiauintydtcnjxtctb/xjexokzpwfsyb/effopwkchzocekdabrqsz/oonlpdirtjrjkmvuxvjdwuhasx/anzxymcvtsjpshk/wgmnsjasfenczanarii?nLz6G8IQH",
"ftp://rjjxnbemcgqdirkrctmvq:5CkK@89.169.203.9/jgdsmyempoohzoravlkgcrauz/ofbi/fqfkzotvwdrv/icgvguluasosmtmktnxavbrfng/katligiisjhpn/jwcijbqivflntz/klmcce/xoanouaiyafj/u/uh?DOllNf#U9AY",
"http://djyqgnlpew.cuuvtx.neztaaxwqo.rndzdbtcof.wvnyhppngr/tnya?ks41JC0dn4e6pmrhzahh3qb6wCDzU",
"https://kafxctkpqr.kejsnnibia.cryxybfwvo.cbvikexrcg.irral/wxfnsxp/hgzflhwvpjisetnahpvdneyskej/otjdkwry/ozixeblclhufqoulcwwlpgooiy/ea/lbqlg/gnruaorx/dfreqzedtjmgnhrlbuigaeqzi/mjbkhyxhcyapgac?1THwzq2r5",
"file://244.65.252.87:1046/itnoaffeywuezfvmkctdaazi/fwyqfikj/rh/ufdyaypkbctoonzhzsnqdjkpobxzw/airnzrxwmacnocrmpa/dlffkuqe/lockgakqmhxgbc/zwpxzdujemfwizeatggs/hjizynljbllirwq/jgwnowwrirjehjwep?GgW8mIUZVv3xebOY3ySl4l",
"http:/ihcxyyghha/ayoexsg/zqf/ntkkyebqcppuraidwihl/krrjl/bqylpebqrzlgvghtqmfacwn/vjfigypqteuyqe/bdrvgweiakujik/fhogoaesbtjyqh/qetzjmr?qbe4edDAlRQXxH0kkW#agPl4osyN2tLvLt7T2QRDyKUb",
"https:/b/aiqcwonqswthnpspypbxjfydfetf/fmuydymzuejw/urqcdi/bzwxohtfhpembnisjswlyet/eeit/fpotyterxgrztodvjjezutqvrh/fieohgtwapiozzepkbjylydqqlicds/qkcgupvlprqivetowutbkwvlu/temuwujmqrcbjqfierqqnsgibh",
"http://86.195.159.88:8786/zqwzohkk/jgdfeoluytiskbpsji/hovdxaypl/viysqatkzdmroydhasziseqmo/zsokxoopaqvygopfkvd/kcwohfrsal/swgozklr/pjnrsksnjd/npjrqngoykqiddfngnvvg/pvmtpqkicj",
"http://inxotxc:h1tvU8rkAzL@jtlbsemydr.lnmkdgprcy.woejcsfypb.vycmuvlobz.refqsawrua/jwizpvtumwzp/t?EipGxsCek2ip#R3LNGrFgkuzy60",
"https:/izdhwoeaex/yifancchxsrnfjxliafgjav/zupznggsucsihzlwvkvwxihnyl/tyrout",
"http://zniekpcyhj.ajgg.enimtsqfgv.vhuvbkdwmi.tlqetyuvya:4096/qndto/llmrysrlbalnnltfxei/ynrmfk/zckhn/apuzmuxcgbuvv/qqymyuyyfedtubarp/vyexoedywlfrzqnfeu/wsqvs/jrvfmop/vlwfqjooajhriwydrfxkzhlfpobib?nbyBZnhIyau1U0OoUsZlMo2#Ot",
"file://iyqoggzfehha:D3lQGnWGVKVQRj5XlVsi6edJdu@55.133.243.122/oqizooy/cgydsxyhwbxc/tvoruimu/zcwcnyk?vgwHPlw3TPwk8iZ6BteN",
"file://gqfmqixlbaeb:U7QNl07GCODE@[3E07::]:8265/xjakjyhjwkaf/sdkhq/afwyjujqthmxrukxhbnh/gblizqsdshe/annd/xwhk/abv/efi/qhoyubtnybhzbuq/jgzxudizb",
"file://a:0Qjv756lK@rgdalivelm.zfhglcfmhi.zpvofrvfle.zhgxbkltuf:9115/ljzkzqhyyetzxwwgm/ftfknxwxrhorpl/jciiaxzfnaxqodvlddkuyqvw/sipdmcgpnufuavxoxowlkscr/dzkhxpwuvbeiphcexbrtyvguo/wobzwxsd/igh/johtkt/gxoiuohyvvlvnucvv/hxmaqzbug#kOeELSGhWgakSoCgsfDz8i",
"http://uflg.shu.wyakcdwh.ocixtaywuc.olo/digwvdhnyhepdsdfronpahzd/lox/lxruxebgyrjrggzt/jgatagcmnresebzrxcojpelecjbair/iuujxiwgtmemvlx/byplnmaqdkvlkpm/lslnxrnaknvupqqecrjonkcv/dyvmyhrwnzthlvrergluzcjmkdxgb/pucrhzpdp/ajeoocvmupxf?vebBkqQIwgCNVvtg4esoqUCPST5M#fsfmBggCpnfmR0kvH",
"http://wblezddguqcison:ziaT2Cs@vdckuauho.nuakkzojvu.dbnjyfrnxk/zratco/wnbpckbdlaoyuedkvgfwc/lrmkukulydnjnpuv/ayaawjkpcxtmxuhwmx/eucythronyknnjgd/niptpkbaneeadmhydoj/htbvhglitirniezousznbpcfokfaje/dlncinmmfmiuchqmrdn/pqcxvjg/hjanaj#LVVPGFIShMHjqGRiy",
"https://ofeqfzlwunufvavqfkmmrhmlslb:J7OA4c2hg@248.210.120.1:8289/geetgghbcrynhbvp/fqutclwgwjsfvkadrgpspgomsvyi/p?1TGfP",
"file://byvvrpfvulqaoyhdj:L9ln4SLJGQolSYoG6b@cidvpyemqt.asiunh.ls.ryoabgdfsj.idzbzxvosw/gwuzv/qgigladrdvirebdknqqqkyepjdsu/jeuz/zdjujpmdxrgzxiqvqcchbsntrxsl/otutbrzuznoqvomfwwlpjb/nziumj/hhfzlcwjumusruudtoxzehvvkm/jidbamvkyjxmh/oauydxxurafzhuevcrslbzqvdox/gqqszbmlkyhdk?Rd5R6",
"http://cg:gkVjlzui@25.159.213.165/byifaod/atsmatyigqhbzisue/plammyhj/kopytfdcjdiaspyoe?kniJwSTkbtU2TOSMGtvosYY",
"https://lgegaakmpknxnl:2G6bnG2ZHb7ypCMj08Ry@dneqpoazvy.ttunduuwde.s.qtgxcvahae.xwitsfafdk/ctluqripgfgsmyyyxl/ctqkelgrbgq/cshxwwz/pptkkafdh/yommtxddcnytoefflutmkgfxjlnxw/xnhlsykeqqcinreyvsbulpny?ibQeNiA5mZo34AzGOQOtnNk7TH",
"http://103.13.121.67/eoqddjyb/xjlejecrvdrdtdfry/pazcfqtzmdxzwldk/rcbczbfgtbgr/sp/majoylnfncveoroclyvydwz/azwrdnqu/qykwvlneeqtitsxbkafquslcdhtcjt/dugigiepoztvzprbdvjahzaxyk/cfpohfhsyqzv?b5Tmhpi93w6#Gm8LpLgmbKsM6ey3hBLzN7B5Cjc3U",
"file://ohidxhfuklcujxhwaneplwnrtafdms:7@[c9:24A:EF:aD:F:C4E6:Ac:9]:14/etcwrdfodgisop/mnxbzsellcimfbhfcxnqjk/tcousvlgknkcjlxuhezjuububo/wmknmyi/tuqnymadnapurahhbxb/nrbffmzadwascn/htfkhapegvwlesvpc/kamhlukivybyulltuxxkp/mwcjtzf/afoxizfsjtzpmfzlgfwddsbmqv?yl1EjLvkPCNNxCnzSYPTNdw#mtU4CN2ejAL",
"http://231.220.210.45/zgiaigvjwkhcjownb/agqksevqgcyihspjnrg/jbbvcbtpwpw/dpftpwgbucot/xicsx/xii/umefdahqrdmmr/z/ccypbkowabxsmtjdyddvdqmrrzw/gddzqjafdboxjsemncdya",
"ftp://mryip.zeysqszsdx.padszuq.igdeto.fiefkqo:5696/wneqbgvzcxc/ypmixakpwzcaz/sczxvkzxyjxoadeepfhiogtrguoxa/gbbyclepvmvwcnarpgwdphjzc/ryklwjkfhkmqe/ojmxbtagtwvqpbztyndfjhmfmuuo/vjrrpfevvzpwzamfwjatvlad/pwuthhhokoxlymrgliekytkshnnno/vyezdmvucvqjqriconw/yckx?U2HDne37nzRnDVTYBeo4E3Ow6",
"http:/qjokbcl/phrxxon/begtaaetynljvducrpcxfkbp/djawsfxquyuqrehdvboao/xxoektddmzujodiwsrfu",
"ftp://228.190.200.135/qninrtfzyiwqfigxtydyonwnq/whbyxez/pbngzsw/xqlkxeepnj/ejfwtaavikjmaqk/mowfhsyhtpsolwdkozdi/ftnhtczeyxvcalchawfpzthbdf/icvekpnbwvocolfpps/ilvwlezzgjqfhbfrwrvwgs/rmqrsoccqeinjcyncmdshumbcp?F1xIX7OS5Y1hnlh95dDk",
"http://222.100.150.244/jedjq/tifhvkruw/hwlevjywfx/hettutbsltjatopqsffookamj/ddvlhygbdtybzcldenovvcnncl/wzjyhnnilupjc/cpcsjpzxzbchgqnaz/nfa/vpijiofnloimfsvoargavoymkeb/vsksyjx#io4YWCIbMNa8uAy",
"http://dxxnvzfspng:3Ia1pm@woxpomrmnt.fmxmupapse.fbm.qjcswoopz.ubfnigsjyp:4641/ygaucnsppmpti/unicrhxddhweibyqoxhsezhvkfs/ccrewwlpijgpomywkt/ldnnbniazqiwesuuel/ehvngaobyfj/igcmhjskqdhsxmbqirlpsaoubc/bmmczgdzhetehajtcrywsqc/kdvezrbphprwlsqsnw/ttgizewqshnbjf/phjebast#xKP3Ek",
"http://zizoikhxd:8Sg3grS3u5w5IsanKn2@2.86.121.243/gmgkxeahiaahxnmxwlwylvvfyax/iz/mpjxipqfhxfaniinzig/muhxjamekrbbd/idapkowgexyumcubzdzexwczouxoxi/hpzfdypgbvmmz/qgfcceuy/nqwjaoeydylqjkmvcfv/oqmlu/ushgfnhizyangugnkogki",
"http://ogjnhcwvr:YE8zSGWcgk@pv.zkaypqrwvc.zynlwqu.qoxbsdtvyi.jfedvvpary/opyo/pnzitpwuzwktevpmsnajqehf/ongvjakt/utdjzst/nvjy/tmzzpvqyvkorgs/ftxzkackxlief/eiqfsaffkfrkhp/veqmhybdejifbjdmxh/nsapgh#IQ",
"http:/qqatcohyntibkhnqswswyxpd/rwtpuxihjtu/ztd/ir/mnnrpauyuhcsiebldlfbpxuwktn/qark/lqklqexmataxkosnorunv/zhsuljssuxwztbrhddkwhn/dmxeubivcvmudjadayyqifakk/fdbknmxmjdxdw?T53Xv2Np8YEi1F3LbYFri",
"ftp://93.203.59.192/cuytxqxxsmmutmhkjaetfg/pixqzfejbtvq/hmchovbkkuisuqqfndwrcxe/tibwoimtefh/rbuwlbplvmxmkcbvwvorkvcjo/bmbgdbdykhtsgyrihnyeazwa/ydnvbpxhbdkzlqnvqh/yyzqgmcmbsnlmplbhtia/nlghhfztoeedyfzgcghmbfadv/xpinmjgq#czNZiHO8",
"http://82.56.201.96/cjsib/qklcxeqbsrcoh#tSKwpP",
"ftp://nvnzqrpguirjddcxefyhlkezydwwg:AcuDlBDS1xEWde@180.36.59.108/nimswbaeugke/yyxohlw/wcbscprbptgzlsqhncpoqbwmt/kjj/pfifainijsausdkresmc/jb/dmzbwzuxfoswbhtgqhmxeuimr/g/jbvduwoqeuwpegyuxqvjraynni/fbqhjgcfgfhmciodxcjcp?Uab4rQN11Z6KiF2",
"ftp://ywcruqjfg.vwnwzelrow.hgmbrjflyk.frzrmqjxbk.tbjddejcni:480/hpyjhpfyevzv/xbvtaktnlfcbgbmj/jdfbedteagikfytqysimkqyfj/nfvnvqjfue/ehzktfqalz/cfysjoioecxtpwcvjh/fwoeixudfpjsygvjto/hydn/ovapakvpevwtrg/rokpnjnkdmzolzscnmtbdiv?2FuSuebgl96xjtv4TzQ",
"ftp:/k/waodexdpwvmur/zaguwbqvavwmuzvyhrgao/sojsf/doeuanvtcugycxkghnxnibqijdukpv/ufnqjighmwxlwkhjui/afbduapmd/fdikoepuzsgrupdmmmcxa/tnmgazereumjbpeitciyrzyzqgpoe?CdKAsjYS#OQaNcaA2PK9KTe2Pa2zwO",
"http://qnhrxhqgur.tvbftk.crruupgxec.toaznijfex.cclemgdwiz/f/baprklcamrkrquleripsz/s/ogezdjzasopsrfgv/tfatmyt/ycsebcsqyvpjxvtvgfksrmquo#JAypKFZR",
"https://yjqjucgqnr.csrebunggb/vcddnfigrkuoe/n/nrxyyngebsbhphgwbzuwpbhk/xpvfplzyrux/hlssfpjylpoougckhqzdm/fwkiwqj/yfotuvtnhkhtkevrolovrhddh/okvzef/mvfaolqnvnkyxuwjopitnlr/vnjwwxbeuodarcpvjojfpymkswlj#aXpK4cMVYMtLyIjX8iHlzBhhDgoMrL",
"http://q:FZ4YPI4syGXwbpNxy5@246.105.84.81:3644/omk/bafcocdyqndkgjqc/fqeaommsuosdyfondrlpjjhgpeme/wipoqedke/fgck/vailhtflcfiosnbwnfvk/lgwxuywp/utovjtpbplnqdnp/hkigzvfczyosxzycvjpeswvpx/azcleshiltmwplrqkqimbdmh?vrUvfPCxQFIr15k",
"file://253.59.27.32:4951/aasko/ytyaqqeaklvpneg/pkrpjvhuoswgcpjah/ltmfnkfmayzpmvksilw/vwe/ccgfb/yeifqgzmirjpaoaly/ovaiwpenskwknhnazitues/pefiokocd/kcyzpliy?R0HRKrSJV29u9MZUs9H8L7o4#EJFi",
"http:/ndfpgzlpvpcc/azgtdwrtugaslneunppnwhltrmnt/zqlyduihoytopqrjbe/sputkujimpsznavrpnwmuwssyaaens?xAgN8m0H2eXO0Ok14eMd7",
"https://187.163.186.205/lewocvpbdnhk/zpzecxp/bgakaceifuodjjk/vtrwqkadjsbwkslpbenlcmpncxyj/rqyyptrazhyty/bq/zfdzwhmqwuuqoqqlgvrk/eqyskursnsrxlxddhthylcylqximjm/aztmrvuihh/rliiqwlmxmni#HOdsfyB40dxMLayoJWXrO4U5MlS",
"file://qsnyikskrg.oimlfvrnlz.rdbsfhbxoh.fffzsomuue.vw:5272/twbpbjpiznzjndrughaxku/acnoympxnjzvudvhdiqgysnuqpkv/djswnzogkh/gpgmhgkkokkovlnouzeoa/kzeaoejpjqviiinncpxaurgkfdgthw/qplcfe/oaevryer/kzsqtflgjwcquivq/eignzixtgpiitqaylwguyrdojnkf/hobacblieh",
"ftp://unkkasfkhv.pwifchllmr.ncegrrlows.mg.uuivggceqk:7081/kcbnjbjufinsksfvffyhcbx/lcnndvse/xrwtwaihscvokcbrzqdimtxmvo/c/x/roqejyqrmmtlpocgna/tqxeklnappcrbcgfibsryg/rhellecjikmahjcykhn/rjzizj/taptfgymanxuarwdy?we2OQ1TzRUImWYvo9QR#v04oMYio9j7fFVreequt",
"ftp://58.224.205.87/druqmabvzqjyyjkztfcvcskzafjizb/ny/ksuwaqnytlxwylmmqsaxmy/vtaftwcatzdztjgbclkabsxvpms/ngijrefqhqzrfjsdpjgnlfalylal/ckcfpisayebolufnwhwxfbnuamsa/kgniymo/lqfslyokefbknjdyzconvybndmaf/torszcxcgehiatrlfilsambdpvsygh#r2",
"http://pfaq.aapffjymu/gjrrttpxivfhdvzf/eesvqglcnyvoo/olpkcqyk/lrspsmqrmisgewisddszbmccnx/hgpq/fhwvurjpflfvjnaifzvlikjkqfyh/zfjkdqjcbggropjgrwufdnybu/uxpbtjeculadltoczfadsf?QN1AAYUFMcHHl",
"http://rdbfmbaf:GrYcY4u29MIh@zgfqtbewiz.cgfgzqgpnp.pwfslpyfzs.yndq.ryn/xaubwwwskxajwtmooz/wexfwfmc/ksbqjuesya/irkfredpblhqlofankgv/kdmjaazfgwnqqvycufmazpy/pkejffkwqehzzigfmpghurj/ghruhwkcwljeyjqx/hlcytprgyGdAym#bluC5",
"https://en.wikipedia.org",
"http://re2c.org",
"https://google.com",
NULL
};
#endif // _RE2C_BENCHMRKS_COMMON_STRINGS_URI_
+311
View File
@@ -0,0 +1,311 @@
#!/bin/env python3
import argparse
import json
import math
import sys
from collections import OrderedDict
plot_preamble = """
\\documentclass[tikz]{standalone}
\\usepackage[utf8]{inputenc}
\\usepackage{amsmath, amssymb, amsfonts}
\\usepackage{tikz, pgfplots, pgfplotstable}
"""
# Use Comic Neue font.
plot_font_comicneue = """
\\usepackage{comicneue}
\\usepackage[T1]{fontenc}
\\renewcommand{\\familydefault}{\\sfdefault}
"""
# Use Computer Modern Bright font.
plot_font_cmbright = """
\\usepackage{cmbright}
\\usepackage[T1]{fontenc}
\\renewcommand{\\familydefault}{\\sfdefault}
"""
# Counterintuitively, 'assume math mode' tricks pgfmathprintnumber into not
# setting math mode, which is needed because Comic Neue does not support math.
#
# Use 'fixed relative' number format with very high precision (the numbers have
# been previously rounded to a few non-zero digits in the fractional part, so
# the trailing zeroes will will not be printed).
plot_begin = """
\\begin{document}
\\def\\plotwidth{%lfin}
\\def\\barwidth{%lfin}
\\pgfplotsset{styleX/.style={
font=\\scriptsize,
xbar,
axis y line*=none,
axis x line=none,
y=0.12in,
width=(\\plotwidth * 0.75),
bar width=\\barwidth,
xshift=\\xplotshift,
yshift=\\yplotshift,
xmax=\\xmax,
xmin=-\\xmax/50,
ymax=0.7,
ymin=0.3 - \\nrows,
ytick=data,
yticklabels from table={\\table}{algo},
every axis title/.style={below right, at={(-0.5in,0)}},
title=\\title,
clip=false,
visualization depends on={x > \\xmax \\as \\xoverflow},
visualization depends on={x > \\xmax ? -x + \\xmax : 0 \\as \\xshift},
nodes near coords={
\\ifdim \\xoverflow pt=1pt \\!\\Large{...}\\scriptsize\\! \\fi
\\pgfmathprintnumber[assume math mode=true]{\\pgfplotspointmeta}
},
nodes near coords style={shift={(axis direction cs:\\xshift,0)}},
nodes near coords style={/pgf/number format/.cd,
fixed relative,
precision = 10,
1000 sep = {\\,}
},
}}
"""
plot_begin_picture = """
\\begin{tikzpicture}
\\def\\xmax{%lf}
"""
plot_middle = """
\\def\\xplotshift{%lfin}
\\def\\yplotshift{%lfin}
\\def\\nrows{%d},
\\def\\title{%s},
\\pgfplotstableread {%s} \\table
\\begin{axis}[styleX]
\\clip(current axis.south west) rectangle(current axis.north east);
\\addplot[fill=lightgray] table[x=value, y expr=-\\coordindex] from \\table;
\\end{axis}
"""
plot_end_picture = """
\\end{tikzpicture}
"""
plot_end = """
\\end{document}
"""
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("input", help="input JSON file")
parser.add_argument("output", help="output TeX file")
parser.add_argument("--relative-to",
help="output CPU time relative to the specified algorithm")
parser.add_argument("--font",
help="use the specified font (supported fonts: cmbright, comicneue)")
return parser.parse_args()
# Generate benchmark title from benchmark name.
def gen_title(oldname):
# Name begins with a letter, so it must be a plain language word.
if oldname[0].isalpha():
return oldname
# Name begins with something else than a letter, treat it as a regexp and
# render as a TeX math formula. This requires adding a few metacharacters.
newname = ""
for char in oldname:
if char in "{*+?":
# Repetition counters must be in superscript.
newname += "^"
newname += char
return "$\\boldsymbol{" + newname + "}$"
# Find index of a group which algorithm contains the given string (stem).
def index_of_algo(group, stem):
if stem == None:
return 0;
for i in range(len(group)):
(algo, _, _, _, _) = group[i]
if stem in algo:
return i
return 0
# Time format: keep integer part precise, round fractional part relative to the
# exponent (similar to PGFPLOTS's "fixed relative, precision = 2" numer format,
# but doesn't round integer part). This is to reduce visual noise on the plot.
#
# Examples: 1004, 195, 13, 3.8, 0.85, 0.017, 0.0048
#
def time_format(time):
order = math.floor(math.log(time, 10))
if order > 0:
return '%.0lf'
else:
return '%%.%dlf' % (-order + 1)
# Split benchmarks into groups by regexp (the first component of the name).
# If the relative mode is on, normalize CPU time by the time of the first
# benchmark in each group.
#
# Expected JSON fomat:
# {
# "benchmarks": [
# {
# "name": <string>,
# ["cpu_time": <number>,]
# ["bin_size": <number>,]
# ["captures": <number>,]
# ["regsize": <number>,] ...
# }, ...
# ], ...
# }
#
def group_benchmarks(benchmarks, relative_to):
benchcount = len(benchmarks)
groups = OrderedDict()
for bench in benchmarks:
name, algo = bench['name'].split('_')
cputime = bench['cpu_time'] if 'cpu_time' in bench else None
binsize = bench['bin_size'] if 'bin_size' in bench else None
captures = bench['captures'] if 'captures' in bench else None
regsize = bench['regsize'] if 'regsize' in bench else None
groups.setdefault(name, []).append(
(algo, cputime, binsize, captures, regsize))
maxtime = 0
avgtime = 0
maxsize = 0
avgsize = 0
maxrows = 0
nbench = 0
benchgroups = OrderedDict()
for name in groups:
group = groups[name]
relto = index_of_algo(group, relative_to)
(_, cputime0, binsize0, captures, regsize) = group[relto]
timetbl = None
if cputime0 != None:
table = 'algo value\n'
for (algo, time, _, _, _) in group:
time = time / (cputime0 if relative_to != None else 1)
maxtime = max(maxtime, time)
avgtime += time
table += ('{%s} ' + time_format(time) + '\n') % (algo, time)
timetbl = table
sizetbl = None
if binsize0 != None:
table = 'algo value\n'
for (algo, _, size, _, _) in group:
maxsize = max(maxsize, size)
avgsize += size
table += '{%s} %lf\n' % (algo, size)
sizetbl = table
title = gen_title(name)
nrows = len(group)
benchgroups[title] = (timetbl, sizetbl, nrows, regsize, captures)
nbench += nrows
maxrows = max(maxrows, nrows)
avgtime /= nbench
avgsize /= nbench
maxtime = min(maxtime, 5 * avgtime)
maxsize = min(maxsize, 5 * avgsize)
return benchgroups, maxtime, maxsize, maxrows
# Generate a Tikz picture with a PGF plot for each benchmark group. Crop
# very long bars, so that they do not squash other bars to the left.
def generate_plot(groups, font):
(benchgroups, maxtime, maxsize, maxrows) = groups
# Plot width is approximately half the usual page width.
plotwidth = 3.5
# Bar width is chosen impirically so that it looks good.
barwidth = 0.08
# Plot height is roughly bar width times maximum group size.
plotheight = 0.15 + maxrows * barwidth * 0.75
plot_time = ''
plot_size = ''
i = 0
for name, benchgroup in benchgroups.items():
even = i % 2 == 0
i += 1
(timetbl, sizetbl, nrows, regsize, captures) = benchgroup
xshift = 0 if even else plotwidth
yshift = -plotheight * (i if even else i - 1)
title = '\\textbf{%s}' % name
if regsize != None and captures != None:
title += ' \\, (%d symbol%s, %d capture%s)' % (
regsize, 's' if regsize > 1 else '',
captures, 's' if captures > 1 else '')
# Generate CPU time plots.
if timetbl != None:
plot_time += plot_middle % (xshift, yshift, nrows, title, timetbl)
# Generate binary size plots.
if sizetbl != None:
plot_size += plot_middle % (xshift, yshift, nrows, title, sizetbl)
# Glue plots together in one TeX document
plot = plot_preamble
if font == 'comicneue':
plot += plot_font_comicneue
elif font == 'cmbright':
plot += plot_font_cmbright
elif font != None:
sys.exit('error: unsupported font: "%s"' % font)
plot += plot_begin % (plotwidth, barwidth)
if plot_time != '':
plot += (plot_begin_picture % maxtime) + plot_time + plot_end_picture
if plot_size != '':
plot += (plot_begin_picture % maxsize) + plot_size + plot_end_picture
plot += plot_end
return plot
def main():
args = parse_args()
with open(args.input) as f:
input = json.load(f)
groups = group_benchmarks(input['benchmarks'], args.relative_to)
plot = generate_plot(groups, args.font)
with open(args.output, 'w') as f:
f.write(plot)
if __name__ == "__main__":
main()
+2
View File
@@ -0,0 +1,2 @@
bin/**
data/*/big
+232
View File
@@ -0,0 +1,232 @@
set(BENCHMARKS
"00__http_rfc7230"
"01__http_simple"
"02__uri_rfc3986"
"03__uri_simple"
"04__apache_log"
"05__datetime"
"06__email"
"07__ipv4"
"10__alt1_2"
"11__alt1_4"
"12__alt1_8"
"13__alt2_2"
"14__alt2_4"
"15__alt2_8"
"16__alt4_2"
"17__alt4_4"
"18__alt4_8"
"20__cat2_0"
"21__cat2_4"
"22__cat2_8"
"23__cat4_0"
"24__cat4_2"
"25__cat4_4"
"26__cat8_0"
"27__cat8_1"
"28__cat8_2"
"30__rep_cat_5_3_2"
"31__rep_cat_13_11_7"
"32__rep_cat_23_19_17"
"33__rep_alt_5_3_2"
"34__rep_alt_13_11_7"
"35__rep_alt_23_19_17"
"36__rep_5_rep_3_rep_2"
"37__rep_13_rep_11_rep_7"
"38__rep_23_rep_19_rep_17"
)
set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(ENG_DIR "${CMAKE_CURRENT_BINARY_DIR}/engines")
set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/gen")
set(BIN_DIR "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(PREGEN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pregen")
set(GEN "")
# kleenex
file(MAKE_DIRECTORY "${ENG_DIR}/kleenex/")
file(MAKE_DIRECTORY "${GEN_DIR}/kleenex/")
set(KLEENEX "${ENG_DIR}/kleenex/kexc")
add_custom_command(
OUTPUT "${KLEENEX}"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/engines/kleenex/getkleenex.sh"
WORKING_DIRECTORY "${ENG_DIR}/kleenex/"
)
# Masked benchmarks for which Kleenex either generates very large output
# (tens of megabytes of C code), or even causes out of memory condition.
set(KLEENEX_MASKED
"34__rep_alt_13_11_7"
"35__rep_alt_23_19_17"
"37__rep_13_rep_11_rep_7"
"38__rep_23_rep_19_rep_17"
)
list(JOIN KLEENEX_MASKED "|" KLEENEX_MASKED_REGEXP)
set(KLEENEX_BENCHMARKS ${BENCHMARKS})
list(FILTER KLEENEX_BENCHMARKS EXCLUDE REGEX "${KLEENEX_MASKED_REGEXP}")
foreach(bench ${KLEENEX_BENCHMARKS})
set(src_file "${SRC_DIR}/kleenex/${bench}.kex")
set(gen_file "${GEN_DIR}/kleenex/${bench}.c")
set(pregen_file "${PREGEN_DIR}/kleenex/${bench}.c")
# optionally regenerate kleenex benchmarks if RE2C_REGEN_BENCHMARKS is set
if(RE2C_REGEN_BENCHMARKS)
file(RELATIVE_PATH rel_src_file "${CMAKE_CURRENT_BINARY_DIR}" "${src_file}")
file(RELATIVE_PATH rel_gen_file "${CMAKE_CURRENT_BINARY_DIR}" "${gen_file}")
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${KLEENEX}" compile "${rel_src_file}" --srcout "${rel_gen_file}" --act=false --la=true
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${gen_file}" "${pregen_file}"
DEPENDS "${src_file}" "${KLEENEX}"
)
else()
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy "${pregen_file}" "${gen_file}"
DEPENDS "${pregen_file}"
)
endif()
list(APPEND GEN "${gen_file}")
endforeach()
# ragel
file(MAKE_DIRECTORY "${ENG_DIR}/ragel/")
file(MAKE_DIRECTORY "${GEN_DIR}/ragel/")
set(RAGEL "${ENG_DIR}/ragel/ragel7")
add_custom_command(
OUTPUT "${RAGEL}"
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/engines/ragel/getragel7.sh"
WORKING_DIRECTORY "${ENG_DIR}/ragel/"
)
foreach(bench ${BENCHMARKS})
set(src_file "${SRC_DIR}/ragel/${bench}.rl")
set(gen_file "${GEN_DIR}/ragel/${bench}.c")
set(pregen_file "${PREGEN_DIR}/ragel/${bench}.c")
# optionally regenerate ragel benchmarks if RE2C_REGEN_BENCHMARKS is set
if(RE2C_REGEN_BENCHMARKS)
file(RELATIVE_PATH rel_src_file "${CMAKE_CURRENT_BINARY_DIR}" "${src_file}")
file(RELATIVE_PATH rel_gen_file "${CMAKE_CURRENT_BINARY_DIR}" "${gen_file}")
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${RAGEL}" "-G2" "${rel_src_file}" -o "${rel_gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${gen_file}" "${pregen_file}"
DEPENDS "${src_file}" "${RAGEL}"
)
else()
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy "${pregen_file}" "${gen_file}"
DEPENDS "${pregen_file}"
)
endif()
list(APPEND GEN "${gen_file}")
endforeach()
# re2c
file(MAKE_DIRECTORY "${GEN_DIR}/re2c/")
set(RE2C "${CMAKE_BINARY_DIR}/re2c")
set(RE2C_FLAGS "--reusable" "--tags" "--no-generation-date" "--no-version")
set(COMMON_RE2C
"${SRC_DIR}/re2c/common.re"
"${SRC_DIR}/re2c/include/fill.re"
"${SRC_DIR}/re2c/include/fill_email.re"
"${SRC_DIR}/re2c/include-eof/fill.re"
"${SRC_DIR}/re2c/include-eof/fill_email.re"
)
foreach(bench ${BENCHMARKS})
foreach(eof "" "-eof")
foreach(alg "tdfa1" "tdfa0" "stadfa")
set(src_file "${SRC_DIR}/re2c/${bench}.re")
set(gen_file "${GEN_DIR}/re2c/${bench}${eof}-${alg}.c")
set(pregen_file "${PREGEN_DIR}/re2c/${bench}${eof}-${alg}.c")
# always regenerate re2c benchmarks (regardless of RE2C_REGEN_BENCHMARKS)
file(RELATIVE_PATH rel_src_file "${CMAKE_CURRENT_BINARY_DIR}" "${src_file}")
file(RELATIVE_PATH rel_gen_file "${CMAKE_CURRENT_BINARY_DIR}" "${gen_file}")
file(RELATIVE_PATH rel_inc_path "${CMAKE_CURRENT_BINARY_DIR}" "${SRC_DIR}/re2c/include${eof}")
set(re2c_flags ${RE2C_FLAGS} "-I" "${rel_inc_path}")
if("${alg}" STREQUAL "tdfa0")
set(re2c_flags ${re2c_flags} "--no-lookahead")
elseif("${alg}" STREQUAL "stadfa")
set(re2c_flags ${re2c_flags} "--stadfa")
endif()
add_custom_command(
OUTPUT "${gen_file}"
COMMAND "${RE2C}" ${re2c_flags} "${rel_src_file}" -o "${rel_gen_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${gen_file}" "${pregen_file}"
DEPENDS "${src_file}" ${COMMON_RE2C} "${RE2C}"
)
list(APPEND GEN "${gen_file}")
endforeach()
endforeach()
endforeach()
# binaries
set(OBJ "")
set(BIN "")
set(CFLAGS "-O3" "-I" "${SRC_DIR}")
set(COMMON_SRC "${SRC_DIR}/common.h")
file(MAKE_DIRECTORY "${BIN_DIR}/kleenex/")
file(MAKE_DIRECTORY "${BIN_DIR}/ragel/")
file(MAKE_DIRECTORY "${BIN_DIR}/re2c/")
foreach(gen_file ${GEN})
foreach(compiler "gcc" "clang")
string(REGEX REPLACE "^${GEN_DIR}(.+)\.c$" "${BIN_DIR}\\1-${compiler}" bin_file "${gen_file}")
set(obj_file "${bin_file}.o")
add_custom_command(
OUTPUT "${bin_file}"
COMMAND "${compiler}" ${CFLAGS} -c "${gen_file}" -o "${obj_file}"
COMMAND "${compiler}" ${CFLAGS} "${obj_file}" -o "${bin_file}"
DEPENDS "${gen_file}" ${COMMON_SRC}
)
list(APPEND OBJ "${obj_file}")
list(APPEND BIN "${bin_file}")
endforeach()
endforeach()
# helper function to transform list
function(regex_replace_list regexp replace var)
set(result "")
foreach(arg ${ARGN})
string(REGEX REPLACE "${regexp}" "${replace}" x "${arg}")
list(APPEND result "${x}")
endforeach()
set(${var} "${result}" PARENT_SCOPE)
endfunction()
# input data
set(DAT)
# Some benchmarks share the same data, like 03__uri_simple and 02__uri_rfc3986.
regex_replace_list("^[0-9]+__([^_]+).*" "\\1" INPUTS ${BENCHMARKS})
list(REMOVE_DUPLICATES INPUTS)
foreach(input ${INPUTS})
set(src_dir "${CMAKE_CURRENT_SOURCE_DIR}/data/${input}")
set(dst_dir "${CMAKE_CURRENT_BINARY_DIR}/data/${input}")
file(GLOB script "${CMAKE_CURRENT_SOURCE_DIR}/data/gen.py")
add_custom_command(
OUTPUT "${dst_dir}/small"
COMMAND "${CMAKE_COMMAND}" -E copy "${src_dir}/small" "${dst_dir}/small"
DEPENDS "${src_dir}/small"
)
add_custom_command(
OUTPUT "${dst_dir}/big"
COMMAND "${script}"
DEPENDS "${script}" "${dst_dir}/small"
WORKING_DIRECTORY "${dst_dir}"
)
list(APPEND DAT "${dst_dir}/small" "${dst_dir}/big")
endforeach()
add_custom_target(bench_submatch_dfa_aot ALL DEPENDS ${BIN} ${DAT})
# benchmark scripts
set(srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set(builddir ".")
configure_file(run.py.in run.py @ONLY)
# override default clean command to keep engines (ragel, kleenex)
set_directory_properties(PROPERTY
CLEAN_NO_CUSTOM On
ADDITIONAL_CLEAN_FILES "${GEN};${OBJ};${BIN};${DAT}"
)
@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 The KMC authors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+192
View File
@@ -0,0 +1,192 @@
SRC_DIR = $(srcdir)/src
ENG_DIR = engines
GEN_DIR = gen
PREGEN_DIR = $(srcdir)/pregen
BIN_DIR = bin
DAT_DIR = data
CFLAGS = -O3 -I $(SRC_DIR)
RAGEL = $(ENG_DIR)/ragel/ragel7
KLEENEX = $(ENG_DIR)/kleenex/kexc
RE2C = $(top_builddir)/re2c
RE2C_FLAGS_COMMON = --reusable --tags --no-generation-date --no-version
RE2C_FLAGS = $(RE2C_FLAGS_COMMON) -I $(SRC_DIR)/re2c/include
RE2C_FLAGS_EOF = $(RE2C_FLAGS_COMMON) -I $(SRC_DIR)/re2c/include-eof
BENCHMARKS = \
00__http_rfc7230 \
01__http_simple \
02__uri_rfc3986 \
03__uri_simple \
04__apache_log \
05__datetime \
06__email \
07__ipv4 \
\
10__alt1_2 \
11__alt1_4 \
12__alt1_8 \
13__alt2_2 \
14__alt2_4 \
15__alt2_8 \
16__alt4_2 \
17__alt4_4 \
18__alt4_8 \
\
20__cat2_0 \
21__cat2_4 \
22__cat2_8 \
23__cat4_0 \
24__cat4_2 \
25__cat4_4 \
26__cat8_0 \
27__cat8_1 \
28__cat8_2 \
\
30__rep_cat_5_3_2 \
31__rep_cat_13_11_7 \
32__rep_cat_23_19_17 \
33__rep_alt_5_3_2 \
34__rep_alt_13_11_7 \
35__rep_alt_23_19_17 \
36__rep_5_rep_3_rep_2 \
37__rep_13_rep_11_rep_7 \
38__rep_23_rep_19_rep_17
COMMON_SRC = $(SRC_DIR)/common.h
GEN_RAGEL = $(patsubst %, $(GEN_DIR)/ragel/%.c, $(BENCHMARKS))
BIN_RAGEL = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_RAGEL))
COMMON_RAGEL = $(COMMON_SRC) $(SRC_DIR)/ragel/common.c
GEN_RE2C_TDFA1 = $(patsubst %, $(GEN_DIR)/re2c/%-tdfa1.c, $(BENCHMARKS))
GEN_RE2C_TDFA0 = $(patsubst %, $(GEN_DIR)/re2c/%-tdfa0.c, $(BENCHMARKS))
GEN_RE2C_STADFA = $(patsubst %, $(GEN_DIR)/re2c/%-stadfa.c, $(BENCHMARKS))
GEN_RE2C_EOF_TDFA1 = $(patsubst %, $(GEN_DIR)/re2c/%-eof-tdfa1.c, $(BENCHMARKS))
GEN_RE2C_EOF_TDFA0 = $(patsubst %, $(GEN_DIR)/re2c/%-eof-tdfa0.c, $(BENCHMARKS))
GEN_RE2C_EOF_STADFA = $(patsubst %, $(GEN_DIR)/re2c/%-eof-stadfa.c, $(BENCHMARKS))
GEN_RE2C = \
$(GEN_RE2C_TDFA1) \
$(GEN_RE2C_TDFA0) \
$(GEN_RE2C_STADFA) \
$(GEN_RE2C_EOF_TDFA1) \
$(GEN_RE2C_EOF_TDFA0) \
$(GEN_RE2C_EOF_STADFA)
BIN_RE2C = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_RE2C))
COMMON_RE2C = \
$(COMMON_SRC) \
$(SRC_DIR)/re2c/common.re \
$(SRC_DIR)/re2c/include/fill.re \
$(SRC_DIR)/re2c/include/fill_email.re \
$(SRC_DIR)/re2c/include-eof/fill.re \
$(SRC_DIR)/re2c/include-eof/fill_email.re
# Masked benchmarks for which Kleenex either generates very large output
# (tens of megabytes of C code), or even causes out of memory condition.
KLEENEX_MASKED = \
34__rep_alt_13_11_7 \
35__rep_alt_23_19_17 \
37__rep_13_rep_11_rep_7 \
38__rep_23_rep_19_rep_17
GEN_KLEENEX = $(patsubst %, $(GEN_DIR)/kleenex/%.c, \
$(filter-out $(KLEENEX_MASKED), $(BENCHMARKS)))
BIN_KLEENEX = $(patsubst $(GEN_DIR)%.c, $(BIN_DIR)%, $(GEN_KLEENEX))
GEN = $(GEN_RAGEL) $(GEN_RE2C) $(GEN_KLEENEX)
BIN_ = $(BIN_RAGEL) $(BIN_RE2C) $(BIN_KLEENEX)
BIN_GCC = $(patsubst %, %-gcc, $(BIN_))
BIN_CLANG = $(patsubst %, %-clang, $(BIN_))
BIN = $(BIN_GCC) $(BIN_CLANG)
OBJ = $(patsubst %, %.o, $(BIN))
# Some benchmarks share the same data, like 03__uri_simple and 02__uri_rfc3986.
DAT = $(patsubst %, $(DAT_DIR)/%/big, \
$(sort $(foreach bench, $(BENCHMARKS), \
$(word 2, $(subst _, , $(bench))))))
all-local: $(BIN) $(DAT)
# always regenerate re2c benchmarks
$(GEN_RE2C_TDFA1): $(GEN_DIR)/%-tdfa1.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS) $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_EOF_TDFA1): $(GEN_DIR)/%-eof-tdfa1.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS_EOF) $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_TDFA0): $(GEN_DIR)/%-tdfa0.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS) --no-lookahead $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_EOF_TDFA0): $(GEN_DIR)/%-eof-tdfa0.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS_EOF) --no-lookahead $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_STADFA): $(GEN_DIR)/%-stadfa.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS) --stadfa $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
$(GEN_RE2C_EOF_STADFA): $(GEN_DIR)/%-eof-stadfa.c: $(SRC_DIR)/%.re $(COMMON_RE2C) $(RE2C)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RE2C) $(RE2C_FLAGS_EOF) --stadfa $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/re2c/$(@F) ; then cp -f $@ $(PREGEN_DIR)/re2c/$(@F) ; fi
# optionally regenerate ragel and kleenex benchmarks
if REGEN_BENCHMARKS
$(GEN_RAGEL): $(GEN_DIR)/%.c: $(SRC_DIR)/%.rl $(COMMON_RAGEL) $(RAGEL)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(RAGEL) -G2 $< -o $@
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/ragel/$(@F) ; then cp -f $@ $(PREGEN_DIR)/ragel/$(@F) ; fi
$(GEN_KLEENEX): $(GEN_DIR)/%.c: $(SRC_DIR)/%.kex $(KLEENEX)
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)$(KLEENEX) compile $< --srcout $@ --act=false --la=true
$(AM_V_at)if ! cmp -s $@ $(PREGEN_DIR)/kleenex/$(@F) ; then cp -f $@ $(PREGEN_DIR)/kleenex/$(@F) ; fi
else
$(GEN_RAGEL) $(GEN_KLEENEX): $(GEN_DIR)/%: $(PREGEN_DIR)/%
$(AM_V_at)mkdir -p $(@D)
$(AM_V_GEN)cp -f $< $@
endif
$(BIN_GCC): $(BIN_DIR)/%-gcc: $(GEN_DIR)/%.c
$(AM_V_at)mkdir -p $(@D)
$(AM_V_at)gcc $(CFLAGS) -c -o $@.o $<
$(AM_V_GEN)gcc $(CFLAGS) -o $@ $@.o
$(BIN_CLANG): $(BIN_DIR)/%-clang: $(GEN_DIR)/%.c
$(AM_V_at)mkdir -p $(@D)
$(AM_V_at)clang $(CFLAGS) -c -o $@.o $<
$(AM_V_GEN)clang $(CFLAGS) -o $@ $@.o
$(DAT): $(DAT_DIR)/%/big: $(DAT_DIR)/%/small
$(AM_V_at)mkdir -p $(@D) && cp $(srcdir)/$(@D)/small $(@D)
$(AM_V_GEN)( cd $(@D) && ../../$(srcdir)/data/gen.py )
$(KLEENEX):
$(AM_V_at)mkdir -p $(@D) && cp $(srcdir)/engines/kleenex/getkleenex.sh $(@D)
$(AM_V_GEN)( cd $(@D) && ./getkleenex.sh )
$(RAGEL):
$(AM_V_at)mkdir -p $(@D) && cp $(srcdir)/engines/ragel/getragel7.sh $(@D)
$(AM_V_GEN)( cd $(@D) && ./getragel7.sh )
clean-local:
$(AM_V_at)rm -f $(GEN) $(OBJ) $(BIN) $(DAT)
+7
View File
@@ -0,0 +1,7 @@
The following benchmarks have been taken from the Kleenex repository
(https://github.com/diku-kmc/kleenexlang) and are licensed under the MIT
license (together with the data generators):
- apache_log
- datetime_to_json
- email
@@ -0,0 +1,17 @@
a
b
aa
bb
aaaa
bbbb
aaaaaaaa
bbbbbbbb
aaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
@@ -0,0 +1,15 @@
ab
ba
aabb
bbaa
aaaabbbb
bbbbaaaa
aaaaaaaabbbbbbbb
bbbbbbbbaaaaaaaa
aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -0,0 +1,13 @@
abab
baba
aabbaabb
bbaabbaa
aaaabbbbaaaabbbb
bbbbaaaabbbbaaaa
aaaaaaaabbbbbbbbaaaaaaaabbbbbbbb
bbbbbbbbaaaaaaaabbbbbbbbaaaaaaaa
aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -0,0 +1,813 @@
99.121.81.108 - - [23/Mar/2015:17:07:24 -0700] "GET /Documents/Ali.htm HTTP/1.1" 200 8449 "http://www.google.com/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=5&ved=0CDkQFjAE&url=http%3A%2F%2Fredlug.com%2FDocuments%2FAli.htm&ei=PKoQVb-gJsnZsASzgYLgDA&usg=AFQjCNEyOmJJeANb79rhMnwQEi73tJtBgg" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0; Touch)"
99.121.81.108 - - [23/Mar/2015:17:07:24 -0700] "GET /cwi.css HTTP/1.1" 404 88 "http://redlug.com/Documents/Ali.htm" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0; Touch)"
31.184.238.152 - - [23/Mar/2015:17:09:08 -0700] "GET /logs/access.log HTTP/1.1" 200 604 "http://www.theknot.com/wedding/baclofen-and-delivery" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:17:09:55 -0700] "GET /logs/access.log HTTP/1.1" 200 865 "http://orderpepcidquickshipping.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36 OPR/19.0.1326.63"
141.101.31.80 - - [23/Mar/2015:17:13:19 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0"
141.101.31.80 - - [23/Mar/2015:17:13:19 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1"
141.101.31.80 - - [23/Mar/2015:17:13:20 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1"
141.101.31.80 - - [23/Mar/2015:17:13:20 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
141.101.31.80 - - [23/Mar/2015:17:13:20 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
141.101.31.80 - - [23/Mar/2015:17:13:21 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.289 Version/12.02"
141.101.31.80 - - [23/Mar/2015:17:13:21 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.289 Version/12.02"
187.24.242.229 - - [23/Mar/2015:17:17:33 -0700] "GET /logs/access.log HTTP/1.1" 200 707 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
180.76.5.65 - - [23/Mar/2015:17:18:42 -0700] "GET /temp/ HTTP/1.1" 200 748 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
31.184.238.152 - - [23/Mar/2015:17:19:39 -0700] "GET /logs/access.log HTTP/1.1" 200 3012 "http://buyglucophageonlinequickshipping.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:17:20:26 -0700] "GET /logs/access.log HTTP/1.1" 200 3276 "http://buy-actos-without-prescription.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 OPR/18.0.1284.68"
193.226.34.229 - - [23/Mar/2015:17:22:00 -0700] "GET /logs/access.log HTTP/1.1" 200 935 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
193.226.34.229 - - [23/Mar/2015:17:22:01 -0700] "GET /Documents/Ali.htm HTTP/1.1" 200 8448 "http://redlug.com/logs/access.log" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
216.108.237.129 - - [23/Mar/2015:17:23:47 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 200 207560 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)"
193.226.34.227 - - [23/Mar/2015:17:25:11 -0700] "GET /logs/access.log HTTP/1.1" 200 1036 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
193.226.34.227 - - [23/Mar/2015:17:25:11 -0700] "GET /Documents/Ali.htm HTTP/1.1" 200 8448 "http://redlug.com/logs/access.log" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:17:30:07 -0700] "GET /logs/access.log HTTP/1.1" 200 4752 "http://www.theknot.com/wedding/without-and-estrace" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:17:30:51 -0700] "GET /logs/access.log HTTP/1.1" 200 5012 "http://naproxen-500mg-order-safely.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
107.23.45.196 - - [23/Mar/2015:17:32:37 -0700] "GET / HTTP/1.1" 200 9589 "http://redlug.com/" "Mozilla/5.0 (compatible; DuckDuckGo-Favicons-Bot/1.0; +http://duckduckgo.com)"
188.165.15.10 - - [23/Mar/2015:17:36:11 -0700] "GET /sitemap/0310Bins.htm HTTP/1.1" 404 88 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
31.184.238.152 - - [23/Mar/2015:17:40:46 -0700] "GET /logs/access.log HTTP/1.1" 200 5640 "http://buyprevacid15mgonlinebe.soup.io" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
141.101.31.80 - - [23/Mar/2015:17:41:27 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; WOW64; Edition Yx) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [23/Mar/2015:17:41:27 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"
141.101.31.80 - - [23/Mar/2015:17:41:27 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"
141.101.31.80 - - [23/Mar/2015:17:41:28 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1"
141.101.31.80 - - [23/Mar/2015:17:41:28 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20100101 Firefox/14.0.1"
141.101.31.80 - - [23/Mar/2015:17:41:29 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) YaBrowser/1.1.1084.5409 Chrome/19.1.1084.5409 Safari/536.5"
141.101.31.80 - - [23/Mar/2015:17:41:29 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) YaBrowser/1.1.1084.5409 Chrome/19.1.1084.5409 Safari/536.5"
31.184.238.152 - - [23/Mar/2015:17:41:32 -0700] "GET /logs/access.log HTTP/1.1" 200 7522 "http://amoxapine-50mg-order-online.over-blog.com" "Mozilla/5.0 (Windows NT 5.1; rv:26.0) Gecko/20100101 Firefox/26.0"
188.116.52.19 - - [23/Mar/2015:17:42:11 -0700] "GET /logs/access.log HTTP/1.1" 200 1451 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
69.250.121.218 - - [23/Mar/2015:17:46:33 -0700] "GET /socview/SV0302TroublesReview.htm HTTP/1.1" 200 3182 "https://www.google.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
69.250.121.218 - - [23/Mar/2015:17:46:33 -0700] "GET /cwi.css HTTP/1.1" 404 89 "http://redlug.com/socview/SV0302TroublesReview.htm" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
180.76.6.136 - - [23/Mar/2015:17:48:42 -0700] "GET /images/ HTTP/1.1" 200 1939 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
157.55.39.135 - - [23/Mar/2015:17:51:04 -0700] "GET /Assorted/VidalReview.htm HTTP/1.1" 200 4223 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
2.218.128.170 - - [23/Mar/2015:17:51:09 -0700] "GET /images/QUBAntiFascism031112.jpg HTTP/1.1" 200 15209 "https://www.google.co.uk/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:17:51:21 -0700] "GET /logs/access.log HTTP/1.1" 200 9156 "http://orderflomaxbr.soup.io" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [23/Mar/2015:17:52:05 -0700] "GET /logs/access.log HTTP/1.1" 200 9364 "http://orderfluticasoneonlineca.soup.io" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
104.128.138.146 - - [23/Mar/2015:17:53:23 -0700] "GET /logs/access.log HTTP/1.1" 200 2371 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
203.130.249.17 - - [23/Mar/2015:17:58:00 -0700] "GET /logs/access.log HTTP/1.1" 200 2391 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:02:09 -0700] "GET /logs/access.log HTTP/1.1" 200 10061 "http://acyclovir400mgv51.aircus.com" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:02:51 -0700] "GET /logs/access.log HTTP/1.1" 200 10307 "http://permethrin-buy-no-prescription.snack.ws" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15"
157.55.39.83 - - [23/Mar/2015:18:03:27 -0700] "GET /paper2004JD/0410Protests.htm HTTP/1.1" 200 2137 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
141.101.31.80 - - [23/Mar/2015:18:09:13 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
141.101.31.80 - - [23/Mar/2015:18:09:14 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; Win64; x64; Edition Yx) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [23/Mar/2015:18:09:14 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; Win64; x64; Edition Yx) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [23/Mar/2015:18:09:15 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Nichrome/self/19"
141.101.31.80 - - [23/Mar/2015:18:09:15 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Nichrome/self/19"
141.101.31.80 - - [23/Mar/2015:18:09:16 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.64"
141.101.31.80 - - [23/Mar/2015:18:09:16 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.64"
54.209.60.63 - - [23/Mar/2015:18:11:43 -0700] "GET /LabHist/1911Linen.htm HTTP/1.1" 200 2583 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25"
74.216.26.213 - - [23/Mar/2015:18:12:43 -0700] "GET /paperarticles/0302YaW.htm HTTP/1.1" 200 4077 "https://www.google.ca/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
74.216.26.213 - - [23/Mar/2015:18:12:44 -0700] "GET /cwi.css HTTP/1.1" 404 88 "http://redlug.com/paperarticles/0302YaW.htm" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:12:54 -0700] "GET /logs/access.log HTTP/1.1" 200 12994 "http://buytrihexyphenidyl.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [23/Mar/2015:18:13:41 -0700] "GET /logs/access.log HTTP/1.1" 200 13208 "http://ordercloxacillinonline.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:24:09 -0700] "GET /logs/access.log HTTP/1.1" 200 13456 "http://ordervermox100mgfastshipping.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:25:18 -0700] "GET /logs/access.log HTTP/1.1" 200 13717 "http://orderneurontin300mgwithoutscript.snack.ws" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
134.249.140.212 - - [23/Mar/2015:18:25:48 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0"
134.249.140.212 - - [23/Mar/2015:18:25:48 -0700] "GET //wp-login.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows NT 6.1; rv:37.0) Gecko/20100101 Firefox/37.0"
134.249.140.212 - - [23/Mar/2015:18:25:49 -0700] "GET / HTTP/1.1" 200 9589 "-" "Mozilla/5.0 (Windows NT 6.1; rv:37.0) Gecko/20100101 Firefox/37.0"
134.249.140.212 - - [23/Mar/2015:18:25:50 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (compatible; bingbot/3.0-alpha; +http://www.bing.com/bingbot.htm)"
134.249.140.212 - - [23/Mar/2015:18:25:50 -0700] "GET //admin/index.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (compatible; bingbot/3.0-alpha; +http://www.bing.com/bingbot.htm)"
134.249.140.212 - - [23/Mar/2015:18:25:50 -0700] "GET //bitrix/admin/index.php?lang=en HTTP/1.1" 404 73 "-" "Mozilla/5.0 (compatible; bingbot/3.0-alpha; +http://www.bing.com/bingbot.htm)"
134.249.140.212 - - [23/Mar/2015:18:25:50 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (compatible; bingbot/3.0-alpha; +http://www.bing.com/bingbot.htm)"
134.249.140.212 - - [23/Mar/2015:18:25:50 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (compatible; bingbot/3.0-alpha; +http://www.bing.com/bingbot.htm)"
134.249.140.212 - - [23/Mar/2015:18:25:51 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (compatible; bingbot/3.0-alpha; +http://www.bing.com/bingbot.htm)"
100.43.81.129 - - [23/Mar/2015:18:28:36 -0700] "GET /logs/access_150122.log HTTP/1.1" 200 1928717 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
24.21.73.217 - - [23/Mar/2015:18:30:43 -0700] "GET /Documents/Ali.htm HTTP/1.1" 200 8450 "https://www.google.com/" "Mozilla/5.0 (Linux; Android 5.0; SM-G900V Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36"
24.21.73.217 - - [23/Mar/2015:18:30:44 -0700] "GET /cwi.css HTTP/1.1" 404 89 "http://redlug.com/Documents/Ali.htm" "Mozilla/5.0 (Linux; Android 5.0; SM-G900V Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36"
54.174.244.172 - - [23/Mar/2015:18:31:21 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.174.244.172 - - [23/Mar/2015:18:31:21 -0700] "GET /documents/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.174.244.172 - - [23/Mar/2015:18:31:21 -0700] "GET /wardoc/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /paper2004jd/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /bins/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /war/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /index.html HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /election07/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /socyouth/ HTTP/1.1" 404 73 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.174.244.172 - - [23/Mar/2015:18:31:21 -0700] "GET /socview/ HTTP/1.1" 200 13443 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.152.206.230 - - [23/Mar/2015:18:31:21 -0700] "GET /temp/ HTTP/1.1" 200 4828 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.174.244.172 - - [23/Mar/2015:18:31:21 -0700] "GET /images/ HTTP/1.1" 200 16831 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0"
54.175.5.159 - - [23/Mar/2015:18:33:30 -0700] "GET /Assorted/StrikerstoSmyth.htm HTTP/1.1" 200 2960 "-" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:35:43 -0700] "GET /logs/access.log HTTP/1.1" 200 18692 "http://buyhydrochlorothiazide5mgcheap.snack.ws" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:36:28 -0700] "GET /logs/access.log HTTP/1.1" 200 18949 "http://ordermobicquickshipping.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.12785 YaBrowser/13.12.1599.12785 Safari/537.36"
141.101.31.80 - - [23/Mar/2015:18:36:38 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.1634 Safari/535.19 YE"
141.101.31.80 - - [23/Mar/2015:18:36:39 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.12 (KHTML, like Gecko) Maxthon/3.0 Chrome/18.0.966.0 Safari/535.12"
141.101.31.80 - - [23/Mar/2015:18:36:39 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.12 (KHTML, like Gecko) Maxthon/3.0 Chrome/18.0.966.0 Safari/535.12"
141.101.31.80 - - [23/Mar/2015:18:36:40 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322)"
141.101.31.80 - - [23/Mar/2015:18:36:40 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322)"
141.101.31.80 - - [23/Mar/2015:18:36:41 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0"
141.101.31.80 - - [23/Mar/2015:18:36:41 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0"
188.165.15.10 - - [23/Mar/2015:18:36:41 -0700] "GET /Election07/News.htm HTTP/1.1" 200 1405 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
80.67.212.62 - - [23/Mar/2015:18:38:09 -0700] "GET /logs/access.log HTTP/1.1" 200 3566 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
204.28.110.118 - - [23/Mar/2015:18:40:18 -0700] "GET /images/2006/OmaghChe.jpg HTTP/1.1" 200 21025 "https://www.google.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
192.42.116.16 - - [23/Mar/2015:18:41:02 -0700] "GET / HTTP/1.1" 200 1273 "http://hundejo.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36"
155.133.19.224 - - [23/Mar/2015:18:42:55 -0700] "GET /logs/access.log HTTP/1.1" 200 3064 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:18:46:32 -0700] "GET /logs/access.log HTTP/1.1" 200 21934 "http://ordercasodexnoscript.forumcircle.com" "Mozilla/5.0 (Windows NT 5.1; rv:26.0) Gecko/20100101 Firefox/26.0"
31.184.238.152 - - [23/Mar/2015:18:47:19 -0700] "GET /logs/access.log HTTP/1.1" 200 22151 "http://zantac-buy-no-rx.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
62.210.205.155 - - [23/Mar/2015:18:50:37 -0700] "GET /logs/access_130901.log HTTP/1.1" 404 88 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
62.210.205.155 - - [23/Mar/2015:18:50:37 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
100.43.81.131 - - [23/Mar/2015:18:51:53 -0700] "GET /pdf/women.pdf HTTP/1.1" 200 34646 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
31.184.238.152 - - [23/Mar/2015:18:57:28 -0700] "GET /logs/access.log HTTP/1.1" 200 23052 "http://buy-furoxone-no-rx.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36 OPR/19.0.1326.63"
31.184.238.152 - - [23/Mar/2015:18:58:15 -0700] "GET /logs/access.log HTTP/1.1" 200 23320 "http://xlmevacor10mg.forumcircle.com" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
141.101.31.80 - - [23/Mar/2015:19:04:50 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19 CoolNovo/2.0.3.55"
141.101.31.80 - - [23/Mar/2015:19:04:50 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:17.0) Gecko/17.0 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:19:04:51 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:17.0) Gecko/17.0 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:19:04:51 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)"
141.101.31.80 - - [23/Mar/2015:19:04:52 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)"
141.101.31.80 - - [23/Mar/2015:19:04:52 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
141.101.31.80 - - [23/Mar/2015:19:04:53 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
5.135.148.171 - - [23/Mar/2015:19:06:09 -0700] "GET / HTTP/1.1" 200 1273 "http://hvd-store.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36"
212.83.131.201 - - [23/Mar/2015:19:07:33 -0700] "GET /logs/access.log HTTP/1.1" 200 3450 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
176.8.89.30 - - [23/Mar/2015:19:07:49 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://minedroid.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
176.8.89.30 - - [23/Mar/2015:19:07:49 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://www.to2ko.ru/" "Opera/9.01 (Windows NT 5.1; U; en)"
176.8.89.30 - - [23/Mar/2015:19:07:49 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://evehost.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
176.8.89.30 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://minedroid.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
176.8.89.30 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://www.to2ko.ru/" "Opera/9.01 (Windows NT 5.1; U; en)"
176.8.89.30 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://evehost.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
46.119.118.191 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://nanoagro.net/" "Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1)"
176.8.89.30 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://www.to2ko.ru/" "Opera/9.01 (Windows NT 5.1; U; en)"
176.8.89.30 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://evehost.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
176.8.89.30 - - [23/Mar/2015:19:07:50 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://minedroid.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
46.119.118.191 - - [23/Mar/2015:19:07:51 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://nanoagro.net/" "Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1)"
46.119.118.191 - - [23/Mar/2015:19:07:52 -0700] "GET /Documents/PunkUSA.htm HTTP/1.1" 200 13496 "http://nanoagro.net/" "Mozilla/4.0 (compatible; MSIE 6.0; AOL 9.0; Windows NT 5.1)"
31.184.238.152 - - [23/Mar/2015:19:08:15 -0700] "GET /logs/access.log HTTP/1.1" 200 28140 "http://buy-stavudine-40mg-cheap.snack.ws" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15"
31.184.238.152 - - [23/Mar/2015:19:08:58 -0700] "GET /logs/access.log HTTP/1.1" 200 28353 "http://gravatar.com/minocycline100mgqo" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
157.55.39.83 - - [23/Mar/2015:19:11:12 -0700] "GET /Election/031106Song.htm HTTP/1.1" 200 1088 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
76.0.172.58 - - [23/Mar/2015:19:13:41 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 200 207560 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
76.0.172.58 - - [23/Mar/2015:19:13:42 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 206 32768 "http://redlug.com/pdf/che_sos.pdf" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
76.0.172.58 - - [23/Mar/2015:19:13:42 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 206 174792 "http://redlug.com/pdf/che_sos.pdf" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
212.83.131.201 - - [23/Mar/2015:19:14:17 -0700] "GET /logs/access.log HTTP/1.1" 200 3794 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
188.165.15.10 - - [23/Mar/2015:19:15:18 -0700] "GET /images/2203e.jpg HTTP/1.1" 200 34981 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
31.184.238.152 - - [23/Mar/2015:19:18:57 -0700] "GET /logs/access.log HTTP/1.1" 200 29921 "http://buyraloxifene.soup.io" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:19:19:44 -0700] "GET /logs/access.log HTTP/1.1" 200 30160 "http://paxil-cr-25mg-buy-cheap.soup.io" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
188.165.15.10 - - [23/Mar/2015:19:27:22 -0700] "GET /paper2004JD/0407Dessian.htm HTTP/1.1" 200 2381 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
31.184.238.152 - - [23/Mar/2015:19:29:31 -0700] "GET /logs/access.log HTTP/1.1" 200 30595 "http://buydoxazosinmesylateonline.snack.ws" "Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [23/Mar/2015:19:30:12 -0700] "GET /logs/access.log HTTP/1.1" 200 30815 "http://gravatar.com/dwelisatatkaagluc" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.13014 YaBrowser/13.12.1599.13014 Safari/537.36"
204.12.216.18 - - [23/Mar/2015:19:31:13 -0700] "GET /Archive/199202AntiSect.htm HTTP/1.1" 200 25462 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727 ; .NET CLR 4.0.30319)"
141.101.31.80 - - [23/Mar/2015:19:32:08 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"
141.101.31.80 - - [23/Mar/2015:19:32:09 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; Edition Yx) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [23/Mar/2015:19:32:09 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; Edition Yx) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [23/Mar/2015:19:32:10 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [23/Mar/2015:19:32:10 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [23/Mar/2015:19:32:10 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"
141.101.31.80 - - [23/Mar/2015:19:32:11 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"
188.165.15.10 - - [23/Mar/2015:19:32:19 -0700] "GET /logs/access_150302.log HTTP/1.1" 200 119881 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
208.67.16.11 - - [23/Mar/2015:19:36:52 -0700] "GET / HTTP/1.1" 200 9589 "-" "Mozilla/5.0 (Windows NT 5.1; rv:32.0) Gecko/20100101 Firefox/32.0"
31.184.238.152 - - [23/Mar/2015:19:40:18 -0700] "GET /logs/access.log HTTP/1.1" 200 33242 "http://3raamoxicillin.aircus.com" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:19:41:04 -0700] "GET /logs/access.log HTTP/1.1" 200 33485 "http://buy-dipyridamole-cheap.snack.ws" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
62.210.205.155 - - [23/Mar/2015:19:49:51 -0700] "GET /logs/access_130820.log HTTP/1.1" 404 88 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
62.210.205.155 - - [23/Mar/2015:19:49:51 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:19:51:00 -0700] "GET /logs/access.log HTTP/1.1" 200 34185 "http://orderrebetolonlineforsale.soup.io" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
178.62.96.206 - - [23/Mar/2015:19:51:35 -0700] "GET /Assorted/NUM.htm HTTP/1.1" 200 6206 "-" "-"
31.184.238.152 - - [23/Mar/2015:19:51:47 -0700] "GET /logs/access.log HTTP/1.1" 200 34553 "http://buycleocin150mgonline.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0"
141.101.31.80 - - [23/Mar/2015:19:59:59 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:20:00:00 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.7.39 Version/11.00"
141.101.31.80 - - [23/Mar/2015:20:00:01 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; WOW64; U; Edition Next; Edition Yx; ru) Presto/2.11.310 Version/12.50"
141.101.31.80 - - [23/Mar/2015:20:00:01 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.1; WOW64; U; Edition Next; Edition Yx; ru) Presto/2.11.310 Version/12.50"
141.101.31.80 - - [23/Mar/2015:20:00:01 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:20:00:02 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101 Firefox/17.0"
31.184.238.152 - - [23/Mar/2015:20:01:15 -0700] "GET /logs/access.log HTTP/1.1" 200 36041 "http://buynorethindroneacetateonlineforsale.soup.io" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:20:01:59 -0700] "GET /logs/access.log HTTP/1.1" 200 36310 "http://buy-ursodiol-safely.soup.io" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.16"
188.165.15.10 - - [23/Mar/2015:20:02:50 -0700] "GET /Election07/?M=A HTTP/1.1" 200 562 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
157.55.39.217 - - [23/Mar/2015:20:09:35 -0700] "GET /Assorted/NUMtime.htm HTTP/1.1" 200 2128 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
46.147.146.177 - - [23/Mar/2015:20:09:51 -0700] "GET / HTTP/1.1" 200 9589 "http://msk9927.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Deepnet Explorer 1.5.0; .NET CLR 1.0.3705)"
31.184.238.152 - - [23/Mar/2015:20:12:50 -0700] "GET /logs/access.log HTTP/1.1" 200 37087 "http://www.theknot.com/wedding/salmeterol-and-shipping" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
104.168.43.19 - - [23/Mar/2015:20:14:34 -0700] "GET /logs/access.log HTTP/1.1" 200 4637 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
144.76.15.235 - - [23/Mar/2015:20:21:56 -0700] "GET / HTTP/1.1" 200 1273 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:21:57 -0700] "GET /robots.txt HTTP/1.1" 200 53 "-" "-"
144.76.15.235 - - [23/Mar/2015:20:21:58 -0700] "GET /?C=N HTTP/1.1" 200 1273 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:21:58 -0700] "GET /?C=M HTTP/1.1" 200 1269 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:21:59 -0700] "GET /?C=S HTTP/1.1" 200 1229 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:00 -0700] "GET /?C=D HTTP/1.1" 200 1273 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:00 -0700] "GET /Archive/ HTTP/1.1" 200 1796 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:01 -0700] "GET /Assorted/ HTTP/1.1" 200 1199 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:01 -0700] "GET /Bins/ HTTP/1.1" 200 488 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:02 -0700] "GET /Documents/ HTTP/1.1" 200 1189 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:02 -0700] "GET /Election/ HTTP/1.1" 200 935 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:02 -0700] "GET /Election07/ HTTP/1.1" 200 562 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:03 -0700] "GET /Index.html HTTP/1.1" 200 490 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:03 -0700] "GET /IntLeftNews/ HTTP/1.1" 200 453 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:04 -0700] "GET /LabHist/ HTTP/1.1" 200 1308 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:04 -0700] "GET /Leaflets/ HTTP/1.1" 200 455 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:05 -0700] "GET /NHS/ HTTP/1.1" 200 450 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:05 -0700] "GET /PaperArchive.htm HTTP/1.1" 200 4083 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:06 -0700] "GET /Publications/ HTTP/1.1" 200 645 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:06 -0700] "GET /Quotes.htm HTTP/1.1" 200 2816 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:07 -0700] "GET /Recent.htm HTTP/1.1" 200 3124 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:07 -0700] "GET /Reps.htm HTTP/1.1" 200 1734 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:08 -0700] "GET /SSUAS.htm HTTP/1.1" 200 1284 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:08 -0700] "GET /SYsup0702.htm HTTP/1.1" 200 47295 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:09 -0700] "GET /Scandals.htm HTTP/1.1" 200 12812 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:09 -0700] "GET /SocYouth/ HTTP/1.1" 200 474 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:10 -0700] "GET /Socialist.htm HTTP/1.1" 200 1050 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:10 -0700] "GET /Socialist/ HTTP/1.1" 200 2930 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:11 -0700] "GET /Struggle-Archive.htm HTTP/1.1" 200 2287 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:11 -0700] "GET /Struggle-FBU.htm HTTP/1.1" 200 4587 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:12 -0700] "GET /Struggle.htm HTTP/1.1" 200 14007 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:12 -0700] "GET /Thumbnails/ HTTP/1.1" 200 398 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:13 -0700] "GET /War/ HTTP/1.1" 200 733 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:13 -0700] "GET /Wardoc/ HTTP/1.1" 200 678 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:14 -0700] "GET /Women/ HTTP/1.1" 200 563 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:14 -0700] "GET /YaW/ HTTP/1.1" 200 757 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:15 -0700] "GET /YaWPR0503.htm HTTP/1.1" 200 4103 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:15 -0700] "GET /YouthArchive.htm HTTP/1.1" 200 5612 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:15 -0700] "GET /broadleft/ HTTP/1.1" 200 232 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:16 -0700] "GET /cwi/ HTTP/1.1" 200 1671 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:16 -0700] "GET /images/ HTTP/1.1" 200 1939 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:16 -0700] "GET /logs/ HTTP/1.1" 200 3273 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:17 -0700] "GET /oldIndex.html HTTP/1.1" 200 2380 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:18 -0700] "GET /old_socialistview.htm HTTP/1.1" 200 4622 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:18 -0700] "GET /oldelectionnews.htm HTTP/1.1" 200 2020 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:19 -0700] "GET /paper2003/ HTTP/1.1" 200 1194 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:19 -0700] "GET /paper2004/ HTTP/1.1" 200 1857 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:20 -0700] "GET /paper2004JD/ HTTP/1.1" 200 1334 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:20 -0700] "GET /paperarticles/ HTTP/1.1" 200 1735 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:21 -0700] "GET /pdf/ HTTP/1.1" 200 694 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:21 -0700] "GET /posters.htm HTTP/1.1" 200 1034 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:21 -0700] "GET /publications.htm HTTP/1.1" 200 5642 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:22 -0700] "GET /sitemap/ HTTP/1.1" 200 544 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:23 -0700] "GET /socialistview.htm HTTP/1.1" 200 4651 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:22 -0700] "GET /socialistPartyArchive/ HTTP/1.1" 200 3042 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:23 -0700] "GET /socview/ HTTP/1.1" 200 1519 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:23 -0700] "GET /stand.htm HTTP/1.1" 200 3709 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:24 -0700] "GET /temp/ HTTP/1.1" 200 748 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:24 -0700] "GET /tmp/ HTTP/1.1" 200 309 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:25 -0700] "GET /tu/ HTTP/1.1" 200 580 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:26 -0700] "GET /youth.htm HTTP/1.1" 200 18293 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:26 -0700] "GET /voice.htm HTTP/1.1" 200 5142 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:27 -0700] "GET /?C=M HTTP/1.1" 200 1269 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:27 -0700] "GET /?C=N HTTP/1.1" 200 1273 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:28 -0700] "GET /?C=S HTTP/1.1" 200 1229 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:28 -0700] "GET /?C=D HTTP/1.1" 200 1273 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:29 -0700] "GET /Archive/?C=N HTTP/1.1" 200 1796 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:29 -0700] "GET /Archive/?C=M HTTP/1.1" 200 1855 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:30 -0700] "GET /Archive/?C=S HTTP/1.1" 200 1807 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:30 -0700] "GET /Archive/?C=D HTTP/1.1" 200 1796 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:30 -0700] "GET /Archive/1969Troops.htm HTTP/1.1" 200 16265 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:31 -0700] "GET /Archive/1970May.htm HTTP/1.1" 200 5241 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:32 -0700] "GET /Archive/1971Intern.htm HTTP/1.1" 200 4769 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:33 -0700] "GET /Archive/197201Unity.htm HTTP/1.1" 200 5844 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:33 -0700] "GET /Archive/1972MayAnswer.htm HTTP/1.1" 200 4039 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:33 -0700] "GET /Archive/1972Pira.htm HTTP/1.1" 200 3873 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:34 -0700] "GET /Archive/1972SeptProt.htm HTTP/1.1" 200 4852 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:34 -0700] "GET /Archive/1972Widgery.htm HTTP/1.1" 200 3672 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:35 -0700] "GET /Archive/1973NovCoalition.htm HTTP/1.1" 200 3250 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:36 -0700] "GET /Archive/197409Intern.htm HTTP/1.1" 200 6101 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:36 -0700] "GET /Archive/1974PTonIreland.htm HTTP/1.1" 200 10322 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:36 -0700] "GET /Archive/1974UWC.htm HTTP/1.1" 200 6787 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:37 -0700] "GET /Archive/1975CRM.htm HTTP/1.1" 200 4623 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:37 -0700] "GET /Archive/1975Ceasefire.htm HTTP/1.1" 200 5863 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:37 -0700] "GET /Archive/1975RepLaw.htm HTTP/1.1" 200 3754 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:38 -0700] "GET /Archive/1976OctDTC.htm HTTP/1.1" 200 2356 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:38 -0700] "GET /Archive/1976OctPP.htm HTTP/1.1" 200 13018 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:38 -0700] "GET /Archive/1976Ulsterbus.htm HTTP/1.1" 200 2969 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:39 -0700] "GET /Archive/1977PeacePEdit.htm HTTP/1.1" 200 3751 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:39 -0700] "GET /Archive/1977UUAC.htm HTTP/1.1" 200 3405 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:40 -0700] "GET /Archive/1979Bennett.htm HTTP/1.1" 200 4490 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:40 -0700] "GET /Archive/1979HB.htm HTTP/1.1" 200 4924 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:41 -0700] "GET /Archive/1979MAvIT.htm HTTP/1.1" 200 4087 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:41 -0700] "GET /Archive/1980HBlock.htm HTTP/1.1" 200 6671 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:41 -0700] "GET /Archive/1980MayHB.htm HTTP/1.1" 200 2193 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:42 -0700] "GET /Archive/1980State.htm HTTP/1.1" 200 4440 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:42 -0700] "GET /Archive/1981GESects.htm HTTP/1.1" 200 14706 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:43 -0700] "GET /Archive/1981HBJuly.htm HTTP/1.1" 200 3505 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:43 -0700] "GET /Archive/1982IyB.htm HTTP/1.1" 200 7589 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:43 -0700] "GET /Archive/1982McGill.htm HTTP/1.1" 200 3446 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:43 -0700] "GET /Archive/1982NHS.htm HTTP/1.1" 200 2150 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:44 -0700] "GET /Archive/1983DTCsgrass.htm HTTP/1.1" 200 2677 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:44 -0700] "GET /Archive/1983Guer.htm HTTP/1.1" 200 7750 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:45 -0700] "GET /Archive/1983MI5.htm HTTP/1.1" 200 2186 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:45 -0700] "GET /Archive/1984supergrass.htm HTTP/1.1" 200 1823 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:46 -0700] "GET /Archive/1983Tressell.htm HTTP/1.1" 200 3324 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:46 -0700] "GET /Archive/1985State.htm HTTP/1.1" 200 13464 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:47 -0700] "GET /Archive/1986AIA.htm HTTP/1.1" 200 15685 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:47 -0700] "GET /Archive/1986Sects.htm HTTP/1.1" 200 11844 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:48 -0700] "GET /Archive/1988CRM.htm HTTP/1.1" 200 8644 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:48 -0700] "GET /Archive/1988Impasse.htm HTTP/1.1" 200 14621 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:49 -0700] "GET /Archive/1988Shoot2Kill.htm HTTP/1.1" 200 3672 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:49 -0700] "GET /Archive/198904MU.htm HTTP/1.1" 200 2367 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:49 -0700] "GET /Archive/198911B6.htm HTTP/1.1" 200 3850 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:50 -0700] "GET /Archive/1989DecPira.htm HTTP/1.1" 200 5175 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:51 -0700] "GET /Archive/1989Mendes.htm HTTP/1.1" 200 2850 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:51 -0700] "GET /Archive/1989NipsaASConf.htm HTTP/1.1" 200 4469 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:52 -0700] "GET /Archive/198911Jail.htm HTTP/1.1" 200 3695 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:52 -0700] "GET /Archive/1989Nipsaconf2.htm HTTP/1.1" 200 2162 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:52 -0700] "GET /Archive/1989PBu.htm HTTP/1.1" 200 2767 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:53 -0700] "GET /Archive/1990Boyne.htm HTTP/1.1" 200 2681 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
31.184.238.152 - - [23/Mar/2015:20:22:53 -0700] "GET /logs/access.log HTTP/1.1" 200 60765 "http://orderticlopidineau.tumblr.com" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
144.76.15.235 - - [23/Mar/2015:20:22:53 -0700] "GET /Archive/1990Brooke.htm HTTP/1.1" 200 2089 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:53 -0700] "GET /Archive/1990OtBridge.htm HTTP/1.1" 200 2441 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:54 -0700] "GET /Archive/199202AntiSect.htm HTTP/1.1" 200 9027 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:55 -0700] "GET /Archive/1993AntiSect.htm HTTP/1.1" 200 4025 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:55 -0700] "GET /Archive/1993H-ATalks.htm HTTP/1.1" 200 9438 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:56 -0700] "GET /Archive/1993NQu.htm HTTP/1.1" 200 19175 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:22:56 -0700] "GET /Archive/199103B6.htm HTTP/1.1" 200 3322 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:03 -0700] "GET /Archive/1993fascists.htm HTTP/1.1" 200 2361 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:04 -0700] "GET /Archive/199401Film.htm HTTP/1.1" 200 3040 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:04 -0700] "GET /Archive/1994CF.htm HTTP/1.1" 200 12416 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:05 -0700] "GET /Archive/7406DLP.htm HTTP/1.1" 200 2518 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:05 -0700] "GET /Archive/7406Derry.htm HTTP/1.1" 200 3242 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:06 -0700] "GET /Archive/7406UWC.htm HTTP/1.1" 200 7482 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:06 -0700] "GET /Archive/74J-Aug.htm HTTP/1.1" 200 3935 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:07 -0700] "GET /Archive/77StoppageIntro.htm HTTP/1.1" 200 4730 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:08 -0700] "GET /Archive/BLFAC.htm HTTP/1.1" 200 4883 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:08 -0700] "GET /Archive/1993SeptPost.htm HTTP/1.1" 200 2775 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:09 -0700] "GET /Archive/1993SeptPost.htm HTTP/1.1" 200 2034 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:09 -0700] "GET /Archive/CommManReview.htm HTTP/1.1" 200 3279 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:09 -0700] "GET /Archive/Contentslist.htm HTTP/1.1" 200 10710 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:10 -0700] "GET /Archive/CorruptionReport.htm HTTP/1.1" 200 5977 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:10 -0700] "GET /Archive/DerryBS.htm HTTP/1.1" 200 2811 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:10 -0700] "GET /Archive/DerryBS1972.htm HTTP/1.1" 200 4458 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:11 -0700] "GET /Archive/NewArchive.htm HTTP/1.1" 200 1966 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:11 -0700] "GET /Archive/OrwellAF.htm HTTP/1.1" 200 2968 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:11 -0700] "GET /Archive/PBList.htm HTTP/1.1" 200 1357 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:12 -0700] "GET /Archive/Rambo.htm HTTP/1.1" 200 3818 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:12 -0700] "GET /Archive/SPArchives1969.htm HTTP/1.1" 200 1648 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:13 -0700] "GET /Archive/SPArchives1970-71.htm HTTP/1.1" 200 864 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:13 -0700] "GET /Archive/SPArchives1972-73.htm HTTP/1.1" 200 2259 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:14 -0700] "GET /Archive/SPArchives1974-75.htm HTTP/1.1" 200 1832 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:14 -0700] "GET /Archive/SPArchives1976-77.htm HTTP/1.1" 200 1606 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:14 -0700] "GET /Archive/SPArchives1978-9.htm HTTP/1.1" 200 2015 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:14 -0700] "GET /Archive/SPArchives1980-81.htm HTTP/1.1" 200 1432 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:15 -0700] "GET /Archive/SPArchives1982-83.htm HTTP/1.1" 200 1259 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:15 -0700] "GET /Archive/SPArchives1984-85.htm HTTP/1.1" 200 3440 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:16 -0700] "GET /Archive/SPArchives1986-87.htm HTTP/1.1" 200 1019 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:16 -0700] "GET /Archive/SPArchives1988-89.htm HTTP/1.1" 200 1928 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:16 -0700] "GET /Archive/SPArchives1990-91.htm HTTP/1.1" 200 1846 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:16 -0700] "GET /Archive/SPArchives1992-93.htm HTTP/1.1" 200 1880 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:17 -0700] "GET /Archive/SPArchives1994-95.htm HTTP/1.1" 200 1091 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:17 -0700] "GET /Archive/Stonewall.htm HTTP/1.1" 200 10794 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:17 -0700] "GET /Archive/UWC1974.htm HTTP/1.1" 200 4583 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:17 -0700] "GET /Archive/testcontents.htm HTTP/1.1" 200 13254 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:18 -0700] "GET /Archive/testcontents2.html HTTP/1.1" 200 1984 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:18 -0700] "GET /Archive/weeklyupdates.htm HTTP/1.1" 200 996 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:18 -0700] "GET /Assorted/?C=N HTTP/1.1" 200 1199 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:19 -0700] "GET /Assorted/?C=M HTTP/1.1" 200 1193 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:19 -0700] "GET /Assorted/?C=S HTTP/1.1" 200 1200 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:20 -0700] "GET /Assorted/?C=D HTTP/1.1" 200 1199 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:20 -0700] "GET /Assorted/2006Debate.htm HTTP/1.1" 200 1838 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:21 -0700] "GET /Assorted/26million.htm HTTP/1.1" 200 3059 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:21 -0700] "GET /Assorted/AirportHS.htm HTTP/1.1" 200 3373 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:22 -0700] "GET /Assorted/AlgiersReview.htm HTTP/1.1" 200 3513 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:22 -0700] "GET /Assorted/BNP.htm HTTP/1.1" 200 3797 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:23 -0700] "GET /Assorted/BSandsReview.htm HTTP/1.1" 200 4989 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:23 -0700] "GET /Assorted/BertiesMoney.htm HTTP/1.1" 200 4824 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:24 -0700] "GET /Assorted/BestObit.htm HTTP/1.1" 200 3854 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:26 -0700] "GET /Assorted/AirportAttack.htm HTTP/1.1" 200 5011 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:27 -0700] "GET /Assorted/BigMacsFilm.htm HTTP/1.1" 200 2574 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:27 -0700] "GET /Assorted/Brown2006Obit.htm HTTP/1.1" 200 3602 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:27 -0700] "GET /Assorted/CGwomen.htm HTTP/1.1" 200 2358 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:27 -0700] "GET /Assorted/ConstantGardener.htm HTTP/1.1" 200 3352 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:28 -0700] "GET /Assorted/Corruption.htm HTTP/1.1" 200 5106 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:28 -0700] "GET /Assorted/FFailsSocialism.htm HTTP/1.1" 200 5267 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:28 -0700] "GET /Assorted/FascistsOut1.htm HTTP/1.1" 200 1930 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:29 -0700] "GET /Assorted/FemaleScience.htm HTTP/1.1" 200 5683 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:29 -0700] "GET /Assorted/GMO.htm HTTP/1.1" 200 4112 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:29 -0700] "GET /Assorted/AirportAttack.htm HTTP/1.1" 200 5754 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:31 -0700] "GET /Assorted/Gama.htm HTTP/1.1" 200 1959 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:31 -0700] "GET /Assorted/Gama050414Dail.htm HTTP/1.1" 200 1578 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:31 -0700] "GET /Assorted/Gama050415.htm HTTP/1.1" 200 2056 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:31 -0700] "GET /Assorted/GoodNightReview.htm HTTP/1.1" 200 2563 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:32 -0700] "GET /Assorted/HipHop.htm HTTP/1.1" 200 7465 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:32 -0700] "GET /Assorted/JH-Bushvisit.htm HTTP/1.1" 200 4146 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:32 -0700] "GET /Assorted/JHProfile0506.htm HTTP/1.1" 200 6006 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:32 -0700] "GET /Assorted/JHSBPost.htm HTTP/1.1" 200 4887 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:33 -0700] "GET /Assorted/JHonNIr.htm HTTP/1.1" 200 1542 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:33 -0700] "GET /Assorted/JHonRacism.htm HTTP/1.1" 200 7415 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:33 -0700] "GET /Assorted/JHonResult.htm HTTP/1.1" 200 2133 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:34 -0700] "GET /Assorted/JLondon.htm HTTP/1.1" 200 10135 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
144.76.15.235 - - [23/Mar/2015:20:23:34 -0700] "GET /Assorted/July05IRA.htm HTTP/1.1" 200 2297 "-" "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)"
31.184.238.152 - - [23/Mar/2015:20:23:36 -0700] "GET /logs/access.log HTTP/1.1" 200 77765 "http://buy-warfarin-lowprice.over-blog.com" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
180.76.5.95 - - [23/Mar/2015:20:23:47 -0700] "GET /Archive/1993H-ATalks.htm HTTP/1.1" 200 3885 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
141.101.31.80 - - [23/Mar/2015:20:27:27 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0"
141.101.31.80 - - [23/Mar/2015:20:27:28 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"
141.101.31.80 - - [23/Mar/2015:20:27:28 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"
141.101.31.80 - - [23/Mar/2015:20:27:29 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 5.1; U; Edition Yx; ru) Presto/2.10.289 Version/12.02"
141.101.31.80 - - [23/Mar/2015:20:27:29 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 5.1; U; Edition Yx; ru) Presto/2.10.289 Version/12.02"
141.101.31.80 - - [23/Mar/2015:20:27:29 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"
141.101.31.80 - - [23/Mar/2015:20:27:30 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11"
31.184.238.152 - - [23/Mar/2015:20:33:25 -0700] "GET /logs/access.log HTTP/1.1" 200 79709 "http://spironolactone-100mg-buy-cheap.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:20:34:12 -0700] "GET /logs/access.log HTTP/1.1" 200 79965 "http://thorazine-buy-online.soup.io" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
31.184.238.152 - - [23/Mar/2015:20:44:06 -0700] "GET /logs/access.log HTTP/1.1" 200 80228 "http://valtrex-order-without-prescription.soup.io" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [23/Mar/2015:20:44:50 -0700] "GET /logs/access.log HTTP/1.1" 200 80458 "http://order-mebendazole-100mg-cheap.snack.ws" "Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [23/Mar/2015:20:54:47 -0700] "GET /logs/access.log HTTP/1.1" 200 80681 "http://www.theknot.com/wedding/ordering-dydrogesterone" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [23/Mar/2015:20:55:26 -0700] "GET /logs/access.log HTTP/1.1" 200 80901 "http://order-alendronate-35mg-no-rx.page.tl" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
157.55.39.217 - - [23/Mar/2015:20:55:36 -0700] "GET /War/LetterHome.htm HTTP/1.1" 200 2637 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
141.101.31.80 - - [23/Mar/2015:20:56:28 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Opera/9.80 (Windows NT 6.0) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [23/Mar/2015:20:56:28 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.96 Safari/537.4"
141.101.31.80 - - [23/Mar/2015:20:56:29 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.96 Safari/537.4"
141.101.31.80 - - [23/Mar/2015:20:56:29 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [23/Mar/2015:20:56:30 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [23/Mar/2015:20:56:30 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
141.101.31.80 - - [23/Mar/2015:20:56:30 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq100.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
202.46.48.97 - - [23/Mar/2015:21:02:26 -0700] "GET /sitemap/0403App.htm HTTP/1.1" 404 88 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:21:05:25 -0700] "GET /logs/access.log HTTP/1.1" 200 83175 "http://buyvaltrex500mgonlineswitzerland.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.12785 YaBrowser/13.12.1599.12785 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:21:06:10 -0700] "GET /logs/access.log HTTP/1.1" 200 83462 "http://gravatar.com/orderlevothroid50mg247" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36"
199.189.84.217 - - [23/Mar/2015:21:11:28 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
31.184.238.152 - - [23/Mar/2015:21:16:01 -0700] "GET /logs/access.log HTTP/1.1" 200 83888 "http://www.theknot.com/wedding/endep-and-special" "Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0"
31.184.238.152 - - [23/Mar/2015:21:16:43 -0700] "GET /logs/access.log HTTP/1.1" 200 84110 "http://glucophage-xr-1000mg-order-without-rx.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36 OPR/19.0.1326.63"
141.101.31.80 - - [23/Mar/2015:21:24:09 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko) YaBrowser/1.1.1084.5409 Chrome/19.1.1084.5409 Safari/536.5"
141.101.31.80 - - [23/Mar/2015:21:24:09 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
141.101.31.80 - - [23/Mar/2015:21:24:09 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1"
141.101.31.80 - - [23/Mar/2015:21:24:10 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 5.1; rv:7.0) Gecko/20100101 Firefox/7.0"
141.101.31.80 - - [23/Mar/2015:21:24:10 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 5.1; rv:7.0) Gecko/20100101 Firefox/7.0"
141.101.31.80 - - [23/Mar/2015:21:24:11 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"
141.101.31.80 - - [23/Mar/2015:21:24:11 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)"
31.184.238.152 - - [23/Mar/2015:21:26:34 -0700] "GET /logs/access.log HTTP/1.1" 200 85958 "http://buyflagylonline.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:21:27:19 -0700] "GET /logs/access.log HTTP/1.1" 200 86206 "http://buy-drospirenone-3mg-online.aircus.com" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.13014 YaBrowser/13.12.1599.13014 Safari/537.36"
162.244.15.179 - - [23/Mar/2015:21:30:31 -0700] "GET /logs/access.log HTTP/1.1" 200 8741 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
77.75.73.17 - - [23/Mar/2015:21:31:05 -0700] "GET /robots.txt HTTP/1.1" 200 535 "-" "Mozilla/5.0 (compatible; SeznamBot/3.2; +http://fulltext.sblog.cz/)"
77.75.73.17 - - [23/Mar/2015:21:31:06 -0700] "GET /Archive/1994CF.htm HTTP/1.1" 200 12416 "-" "Mozilla/5.0 (compatible; SeznamBot/3.2; +http://fulltext.sblog.cz/)"
37.59.30.209 - - [23/Mar/2015:21:34:32 -0700] "GET /logs/access.log HTTP/1.1" 200 8849 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
157.55.39.135 - - [23/Mar/2015:21:35:05 -0700] "GET /Bins/ITimes031020.htm HTTP/1.1" 200 3196 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
31.184.238.152 - - [23/Mar/2015:21:37:11 -0700] "GET /logs/access.log HTTP/1.1" 200 87510 "http://buyvenlafaxineonlinelowprice.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36 OPR/20.0.1387.64"
31.184.238.152 - - [23/Mar/2015:21:38:00 -0700] "GET /logs/access.log HTTP/1.1" 200 87789 "http://ordercefdinironlinewithoutprescript.snack.ws" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.16"
77.75.73.17 - - [23/Mar/2015:21:41:26 -0700] "GET /Archive/1974UWC.htm HTTP/1.1" 200 7415 "-" "Mozilla/5.0 (compatible; SeznamBot/3.2; +http://fulltext.sblog.cz/)"
178.137.19.232 - - [23/Mar/2015:21:43:27 -0700] "GET /cwi/Bush2.htm HTTP/1.1" 200 68762 "http://redlug.com/cwi/Bush2.htm" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
188.165.15.10 - - [23/Mar/2015:21:44:20 -0700] "GET /Socialist/0511Kashmir.htm HTTP/1.1" 200 2669 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
103.27.24.113 - - [23/Mar/2015:21:47:29 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:21:47:47 -0700] "GET /logs/access.log HTTP/1.1" 200 88800 "http://buy-propranolol-10-mg-online-au.page.tl" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [23/Mar/2015:21:48:32 -0700] "GET /logs/access.log HTTP/1.1" 200 89027 "http://gravatar.com/postmiclamarsiobrab" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
192.99.221.220 - - [23/Mar/2015:21:51:54 -0700] "GET /logs/access.log HTTP/1.1" 200 9848 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
141.101.31.80 - - [23/Mar/2015:21:52:05 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:21:52:06 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11"
141.101.31.80 - - [23/Mar/2015:21:52:06 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11"
141.101.31.80 - - [23/Mar/2015:21:52:07 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0"
141.101.31.80 - - [23/Mar/2015:21:52:07 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0"
141.101.31.80 - - [23/Mar/2015:21:52:07 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) YaBrowser/1.1.1084.5409 Chrome/19.1.1084.5409 Safari/536.5"
141.101.31.80 - - [23/Mar/2015:21:52:08 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) YaBrowser/1.1.1084.5409 Chrome/19.1.1084.5409 Safari/536.5"
157.55.39.217 - - [23/Mar/2015:21:52:58 -0700] "GET /paperarticles/nov01-woa.htm HTTP/1.1" 200 4094 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
104.168.48.83 - - [23/Mar/2015:21:54:03 -0700] "GET /logs/access.log HTTP/1.1" 200 9343 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:21:59:15 -0700] "GET /logs/access.log HTTP/1.1" 200 91574 "http://ordercitalopramlowprice.snack.ws" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
157.55.39.237 - - [23/Mar/2015:22:00:10 -0700] "GET /Documents/JH-Dail.htm HTTP/1.1" 200 3938 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
216.244.83.168 - - [23/Mar/2015:22:00:34 -0700] "GET / HTTP/1.1" 200 1273 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:34 -0700] "GET /?C=N;O=D HTTP/1.1" 200 1274 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:35 -0700] "GET /?C=M;O=A HTTP/1.1" 200 1269 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:35 -0700] "GET /?C=S;O=A HTTP/1.1" 200 1229 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:35 -0700] "GET /?C=D;O=A HTTP/1.1" 200 1273 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:35 -0700] "GET /Archive/ HTTP/1.1" 200 1796 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:35 -0700] "GET /Assorted/ HTTP/1.1" 200 1199 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:36 -0700] "GET /Bins/ HTTP/1.1" 200 488 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:36 -0700] "GET /Documents/ HTTP/1.1" 200 1189 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:36 -0700] "GET /Election/ HTTP/1.1" 200 935 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:36 -0700] "GET /Election07/ HTTP/1.1" 200 562 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:36 -0700] "GET /Index.html HTTP/1.1" 200 490 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /IntLeftNews/ HTTP/1.1" 200 453 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /LabHist/ HTTP/1.1" 200 1308 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /Leaflets/ HTTP/1.1" 200 455 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /NHS/ HTTP/1.1" 200 450 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /PaperArchive.htm HTTP/1.1" 200 3349 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /Publications/ HTTP/1.1" 200 645 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:37 -0700] "GET /Quotes.htm HTTP/1.1" 200 2816 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:38 -0700] "GET /Recent.htm HTTP/1.1" 200 3124 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:38 -0700] "GET /Reps.htm HTTP/1.1" 200 1734 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:38 -0700] "GET /SSUAS.htm HTTP/1.1" 200 1284 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:38 -0700] "GET /SYsup0702.htm HTTP/1.1" 200 15136 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:38 -0700] "GET /Scandals.htm HTTP/1.1" 200 12812 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:39 -0700] "GET /SocYouth/ HTTP/1.1" 200 474 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:39 -0700] "GET /Socialist.htm HTTP/1.1" 200 1050 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:39 -0700] "GET /Socialist/ HTTP/1.1" 200 2930 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:39 -0700] "GET /Struggle-Archive.htm HTTP/1.1" 200 2288 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:39 -0700] "GET /Struggle-FBU.htm HTTP/1.1" 200 4588 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:39 -0700] "GET /Struggle.htm HTTP/1.1" 200 14631 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:40 -0700] "GET /Thumbnails/ HTTP/1.1" 200 398 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:40 -0700] "GET /War/ HTTP/1.1" 200 733 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:40 -0700] "GET /Wardoc/ HTTP/1.1" 200 678 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:41 -0700] "GET /Women/ HTTP/1.1" 200 563 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:41 -0700] "GET /YaW/ HTTP/1.1" 200 757 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:41 -0700] "GET /YaWPR0503.htm HTTP/1.1" 200 3372 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:41 -0700] "GET /YouthArchive.htm HTTP/1.1" 200 5611 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:41 -0700] "GET /broadleft/ HTTP/1.1" 200 232 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:41 -0700] "GET /cwi/ HTTP/1.1" 200 1671 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:42 -0700] "GET /images/ HTTP/1.1" 200 1939 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:42 -0700] "GET /logs/ HTTP/1.1" 200 3272 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:42 -0700] "GET /oldIndex.html HTTP/1.1" 200 2379 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:43 -0700] "GET /old_socialistview.htm HTTP/1.1" 200 4516 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:43 -0700] "GET /oldelectionnews.htm HTTP/1.1" 200 2019 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:43 -0700] "GET /paper2003/ HTTP/1.1" 200 1194 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:43 -0700] "GET /paper2004/ HTTP/1.1" 200 1857 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:43 -0700] "GET /paper2004JD/ HTTP/1.1" 200 1334 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:44 -0700] "GET /paperarticles/ HTTP/1.1" 200 1735 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:44 -0700] "GET /pdf/ HTTP/1.1" 200 694 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:44 -0700] "GET /posters.htm HTTP/1.1" 200 1656 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:45 -0700] "GET /publications.htm HTTP/1.1" 200 5639 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:45 -0700] "GET /robots.txt HTTP/1.1" 200 53 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:45 -0700] "GET /sitemap.xml HTTP/1.1" 200 198 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:45 -0700] "GET /sitemap/ HTTP/1.1" 200 544 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:45 -0700] "GET /socialistPartyArchive/ HTTP/1.1" 200 3217 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:46 -0700] "GET /socialistview.htm HTTP/1.1" 200 4650 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:46 -0700] "GET /socview/ HTTP/1.1" 200 1519 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:46 -0700] "GET /stand.htm HTTP/1.1" 200 3709 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:46 -0700] "GET /temp/ HTTP/1.1" 200 748 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:46 -0700] "GET /tmp/ HTTP/1.1" 200 309 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:47 -0700] "GET /tu/ HTTP/1.1" 200 580 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:47 -0700] "GET /voice.htm HTTP/1.1" 200 4419 "-" "-"
216.244.83.168 - - [23/Mar/2015:22:00:47 -0700] "GET /youth.htm HTTP/1.1" 200 6786 "-" "-"
180.76.5.145 - - [23/Mar/2015:22:04:05 -0700] "GET /Archive/7406DLP.htm HTTP/1.1" 200 3148 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
37.130.227.133 - - [23/Mar/2015:22:04:30 -0700] "GET /logs/ HTTP/1.1" 200 37973 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01"
37.130.227.133 - - [23/Mar/2015:22:04:32 -0700] "GET /logs/access_150324.log HTTP/1.1" 200 4361818 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; de) Opera 11.01"
31.184.238.152 - - [23/Mar/2015:22:09:34 -0700] "GET /logs/access.log HTTP/1.1" 200 99153 "http://ordertetracycline250mgcheap.snack.ws" "Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.16"
188.165.15.10 - - [23/Mar/2015:22:10:12 -0700] "GET /images/Nipsa04/?C=D;O=A HTTP/1.1" 200 471 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
31.184.238.152 - - [23/Mar/2015:22:10:21 -0700] "GET /logs/access.log HTTP/1.1" 200 99555 "http://orderaripiprazoleonlinecheap.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0"
68.190.29.39 - - [23/Mar/2015:22:10:51 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 200 207560 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.14 (KHTML, like Gecko) Version/6.0.1 Safari/536.26.14"
100.43.91.12 - - [23/Mar/2015:22:12:34 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
157.55.39.134 - - [23/Mar/2015:22:12:37 -0700] "GET /Socialist/06/0603Water.htm HTTP/1.1" 200 3381 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
157.55.39.134 - - [23/Mar/2015:22:12:37 -0700] "GET /pdf/SCWpamphlet.pdf HTTP/1.1" 200 376103 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 (compatible; bingbot/2.0; http://www.bing.com/bingbot.htm)"
68.190.29.39 - - [23/Mar/2015:22:17:24 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 200 207560 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/536.26.14 (KHTML, like Gecko) Version/6.0.1 Safari/536.26.14"
141.101.31.80 - - [23/Mar/2015:22:19:44 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
141.101.31.80 - - [23/Mar/2015:22:19:45 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0"
141.101.31.80 - - [23/Mar/2015:22:19:45 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0"
141.101.31.80 - - [23/Mar/2015:22:19:46 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25"
141.101.31.80 - - [23/Mar/2015:22:19:46 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25"
141.101.31.80 - - [23/Mar/2015:22:19:46 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blondebitch.soup.io/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)"
141.101.31.80 - - [23/Mar/2015:22:19:47 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)"
31.184.238.152 - - [23/Mar/2015:22:19:59 -0700] "GET /logs/access.log HTTP/1.1" 200 102435 "http://gravatar.com/orderuroxatral10mgfastshipping" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [23/Mar/2015:22:20:45 -0700] "GET /logs/access.log HTTP/1.1" 200 102652 "http://buytopiramateonlinecheap.snack.ws" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
46.147.146.177 - - [23/Mar/2015:22:27:22 -0700] "GET / HTTP/1.1" 200 9589 "http://msk9017.apishops.ru/" "Opera/7.54 (Windows NT 5.1; U) [pl]"
46.147.146.177 - - [23/Mar/2015:22:27:23 -0700] "GET / HTTP/1.1" 200 9589 "http://msk9017.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1"
46.147.146.177 - - [23/Mar/2015:22:27:23 -0700] "GET / HTTP/1.1" 200 9589 "http://msk9017.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"
46.147.146.177 - - [23/Mar/2015:22:27:24 -0700] "GET / HTTP/1.1" 200 9589 "http://msk9017.apishops.ru/" "Mozilla/1.22 (compatible; MSIE 2.0; Windows 95)"
31.184.238.152 - - [23/Mar/2015:22:30:35 -0700] "GET /logs/access.log HTTP/1.1" 200 103562 "http://ordercefaclorfastshipping.snack.ws" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:22:31:19 -0700] "GET /logs/access.log HTTP/1.1" 200 103815 "http://buycabergolinequickshipping.snack.ws" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
157.55.39.217 - - [23/Mar/2015:22:31:49 -0700] "GET /Assorted/SSP2005.htm HTTP/1.1" 200 3702 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
31.184.238.152 - - [23/Mar/2015:22:41:20 -0700] "GET /logs/access.log HTTP/1.1" 200 104261 "http://buyacyclovir400mgonlinenorx.over-blog.com" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:22:42:07 -0700] "GET /logs/access.log HTTP/1.1" 200 104521 "http://buymetoclopramidequickdelivery.soup.io" "Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0"
213.85.255.195 - - [23/Mar/2015:22:45:49 -0700] "GET /y?Z=qLDzmn02h0F4zM6H1g2+pdVyIWVCyge952wbHDdfpnT2sN1Z7+94GQYNYoO/7/hY5gFZ9vcFQPKdwNaCYWLkyn8XVgKtgPKRvXQ1zZBPoWNI17Qpdqh7a/x7qASY/mjoiGS8gZqeox0iEte1L0yif+ng59opuu24Ju1MNh1JBRhkufochxr0x/gYCo6JZeu1q2pt94WFQPWDgkJLAifViG4NtXX96e5Ro1Kou7/GsniSxMXxO0DFjl5v2w7n+ruQglpoOO1qk+jWm65sHcvoD5rWJ/1RgqI8eB7j8fUJubwJoIOExtrQX7ZWnsH/2HSongx5wvhdW829vTSqFgrIghzJ7nDz9LIgta09XwU2yT1QCmHLpMy5KvALY1keTo+gQcfGFNwn5tgs1MiYt72QDNIXaO8ic811R5moMbG2qgkk2rjDM6eiwZIgrElKAsRB/CqLwmQ5/IWSWvtZuN8lDSzyfOK15+9luPfLNSmBoKkpA2skaxpFfKuSrip73oojL46tWxRxPWkHxgL81XqexiblZ9IV+kPCVzntmDXILkv6/HzQvdzGn8x33af5CEtxOyUn2yneghCqHIRGYDZyLyclFo2bhZw7lGGru3qzmCe4xXDkEcZB/ntqHAEd6WBDJnrqP3dL4tB3SsU7KEvUbT11akwklQix4RruRHyzgysbfQS4geifRkEcZ4sokCG9a3nItj93cwuQMED8BtjDOCebAY0OB5XHWMk6w9pLUcR+b8LDtJBViw+mtMHcJyLDEZcFzvpmKzuQOsBZGLhwvinYfA9G7lJW0lXnR7zCMTZ5jvna/NzJQJR+HEWfGJGr92xdZ92 HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [23/Mar/2015:22:45:51 -0700] "GET /M?u=Iw1oSPOBRs1ITWMy62w1gYe+1kqyyJtIcAy6tuhm5P60SWkQ4wy++0+ZW9iNqlxAR/V3xyuMk132L7YlBWFHZhRiP1Ssz/04pVyuL40a8oi6FbFgKSJIl4HH5zBJqxnkze1IwFPumHj7jIGXj2xd/gqgxZ9dqHumDiQsC+FKhN/oRMRQE+Z9l5NMJT9ap78gEsstgBLDhbXy68TgBxiaONNAFBAc3JksH3OVFuAmZGzcLq8vPMDKqMJrv232zK/Y17LfTr1lRXf5Gk3rYCzCH7VoyiM1cwfCZ1/LPR6+XwNB61n5SoJ6YlATtRAyPItuW+k+ddG0UpGuQ5yNI4r5lxvXGZ02p94WOdmgm3DSuPWn7SyqSm7twfaJAuduuuTFAxEpPM9pdzcv/Z9Bf2tpw316Lp/3FwXpqoKPZ74UOYwRiYIOdUSe7mWMgZlRykRQ5OHBbg9wXa8Vs8prBA2WvmmfrFjGEZt HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
141.101.31.80 - - [23/Mar/2015:22:47:17 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:22:47:18 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.28) Gecko/20120306 Firefox/3.6.28 sputnik 2.5.2.8"
141.101.31.80 - - [23/Mar/2015:22:47:18 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.28) Gecko/20120306 Firefox/3.6.28 sputnik 2.5.2.8"
141.101.31.80 - - [23/Mar/2015:22:47:19 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:22:47:19 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Firefox/17.0"
141.101.31.80 - - [23/Mar/2015:22:47:20 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; MRA 6.0 (build 6001)) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [23/Mar/2015:22:47:20 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; MRA 6.0 (build 6001)) Presto/2.12.388 Version/12.11"
31.184.238.152 - - [23/Mar/2015:22:52:16 -0700] "GET /logs/access.log HTTP/1.1" 200 107901 "http://buycalcitriolonline.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:22:53:02 -0700] "GET /logs/access.log HTTP/1.1" 200 108155 "http://buypromethazineonlinewholesale.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
77.27.19.57 - - [23/Mar/2015:22:54:45 -0700] "GET /logs/access.log HTTP/1.1" 200 108411 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:2.0b8pre) Gecko/20101011 Firefox/4.0b8pre"
180.76.5.78 - - [23/Mar/2015:22:55:34 -0700] "GET /paper2004JD/?N=D HTTP/1.1" 200 1334 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
36.231.170.34 - - [23/Mar/2015:23:02:48 -0700] "GET /logs/access.log HTTP/1.1" 200 13115 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
157.55.39.237 - - [23/Mar/2015:23:02:54 -0700] "GET /paperarticles/sv0602sy.htm HTTP/1.1" 200 2305 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
31.184.238.152 - - [23/Mar/2015:23:03:24 -0700] "GET /logs/access.log HTTP/1.1" 200 109225 "http://www.theknot.com/wedding/acillin-and-without" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0"
31.184.238.152 - - [23/Mar/2015:23:04:10 -0700] "GET /logs/access.log HTTP/1.1" 200 109457 "http://x0luvox50mg.forumcircle.com" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36 OPR/19.0.1326.63"
183.89.175.19 - - [23/Mar/2015:23:04:10 -0700] "GET /logs/access.log HTTP/1.1" 200 12589 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
72.81.177.197 - - [23/Mar/2015:23:06:15 -0700] "GET /socview/SV0302TroublesReview.htm HTTP/1.1" 200 3182 "https://www.google.com/" "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4"
72.81.177.197 - - [23/Mar/2015:23:06:18 -0700] "GET /cwi.css HTTP/1.1" 404 89 "http://redlug.com/socview/SV0302TroublesReview.htm" "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4"
31.184.238.152 - - [23/Mar/2015:23:14:24 -0700] "GET /logs/access.log HTTP/1.1" 200 110539 "http://buydoxazosinmesylate1mgonlinequickshipping.soup.io" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
141.101.31.80 - - [23/Mar/2015:23:15:08 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0"
141.101.31.80 - - [23/Mar/2015:23:15:08 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11"
141.101.31.80 - - [23/Mar/2015:23:15:09 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11"
141.101.31.80 - - [23/Mar/2015:23:15:09 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; MRA 6.0 (build 5970)) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [23/Mar/2015:23:15:10 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; MRA 6.0 (build 5970)) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [23/Mar/2015:23:15:10 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; Edition Yx) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [23/Mar/2015:23:15:10 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; Edition Yx) Presto/2.12.388 Version/12.11"
31.184.238.152 - - [23/Mar/2015:23:15:11 -0700] "GET /logs/access.log HTTP/1.1" 200 112378 "http://desloratadine5mgc1.forumcircle.com" "Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0"
31.184.238.152 - - [23/Mar/2015:23:25:16 -0700] "GET /logs/access.log HTTP/1.1" 200 112594 "http://orderclofazimineonline.over-blog.com" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:23:25:57 -0700] "GET /logs/access.log HTTP/1.1" 200 112848 "http://clomiphene-order-online.soup.io" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15"
188.165.15.10 - - [23/Mar/2015:23:28:42 -0700] "GET /Documents/TDNPPt2.htm HTTP/1.1" 200 8913 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
122.252.228.137 - - [23/Mar/2015:23:34:14 -0700] "GET /logs/access.log HTTP/1.1" 200 12989 "https://www.google.co.in/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
218.188.208.223 - - [23/Mar/2015:23:35:16 -0700] "GET /Documents/Ali.htm HTTP/1.1" 200 8450 "https://www.google.com.hk/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"
218.188.208.223 - - [23/Mar/2015:23:35:17 -0700] "GET /cwi.css HTTP/1.1" 404 88 "http://redlug.com/Documents/Ali.htm" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"
218.188.208.223 - - [23/Mar/2015:23:35:18 -0700] "GET /favicon.ico HTTP/1.1" 404 89 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"
122.252.228.137 - - [23/Mar/2015:23:35:40 -0700] "GET / HTTP/1.1" 200 1273 "https://www.google.co.in/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:23:36:05 -0700] "GET /logs/access.log HTTP/1.1" 200 114449 "http://www.theknot.com/wedding/hydroxyzine-and-delivery" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
193.226.34.229 - - [23/Mar/2015:23:36:32 -0700] "GET /logs/access.log HTTP/1.1" 200 13169 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
193.226.34.229 - - [23/Mar/2015:23:36:32 -0700] "GET /socview/SV0302TroublesReview.htm HTTP/1.1" 200 3184 "http://redlug.com/logs/access.log" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:23:36:52 -0700] "GET /logs/access.log HTTP/1.1" 200 115248 "http://orderacyclovironlinenoscript.soup.io" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
188.165.15.10 - - [23/Mar/2015:23:37:05 -0700] "GET /Archive/?C=D;O=A HTTP/1.1" 200 1796 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
193.226.34.226 - - [23/Mar/2015:23:41:21 -0700] "GET /logs/access.log HTTP/1.1" 200 13870 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
193.226.34.226 - - [23/Mar/2015:23:41:22 -0700] "GET /socview/SV0302TroublesReview.htm HTTP/1.1" 200 2434 "http://redlug.com/logs/access.log" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
141.101.31.80 - - [23/Mar/2015:23:42:41 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0) Gecko/20100101 Firefox/15.0"
141.101.31.80 - - [23/Mar/2015:23:42:41 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0"
141.101.31.80 - - [23/Mar/2015:23:42:42 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0"
141.101.31.80 - - [23/Mar/2015:23:42:42 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [23/Mar/2015:23:42:42 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [23/Mar/2015:23:42:43 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2"
141.101.31.80 - - [23/Mar/2015:23:42:43 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2"
177.55.254.194 - - [23/Mar/2015:23:46:22 -0700] "GET /logs/access.log HTTP/1.1" 200 13975 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
193.226.34.228 - - [23/Mar/2015:23:46:39 -0700] "GET /logs/access.log HTTP/1.1" 200 13384 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
193.226.34.228 - - [23/Mar/2015:23:46:40 -0700] "GET /socview/SV0302TroublesReview.htm HTTP/1.1" 200 2434 "http://redlug.com/logs/access.log" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:23:47:07 -0700] "GET /logs/access.log HTTP/1.1" 200 118421 "http://www.theknot.com/wedding/sale-and-glucovance" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [23/Mar/2015:23:47:51 -0700] "GET /logs/access.log HTTP/1.1" 200 118683 "http://www.theknot.com/wedding/maxalt-and-rx" "Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [23/Mar/2015:23:57:51 -0700] "GET /logs/access.log HTTP/1.1" 200 118902 "http://14ursodiol.forumcircle.com" "Mozilla/5.0 (Windows NT 6.1; rv:26.0) Gecko/20100101 Firefox/26.0"
196.46.125.2 - - [23/Mar/2015:23:59:11 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:12 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:13 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:13 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:14 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:15 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:15 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:16 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:16 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:17 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:18 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:18 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:19 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:20 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:20 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:21 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:22 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:22 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:23 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:24 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:24 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:25 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:26 -0700] "GET //components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:28 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:28 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:29 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:30 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:30 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:31 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:32 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:32 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:33 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:34 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:35 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:35 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:36 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:37 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:37 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:38 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:39 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:39 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:40 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:41 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:41 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:42 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
196.46.125.2 - - [23/Mar/2015:23:59:43 -0700] "GET /logs//components/com_jnews/includes/openflashchart/php-ofc-library/ofc_upload_image.php?name=magic.php.pHp HTTP/1.1" 404 73 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2) Gecko/20100115 Firefox/3.6"
157.55.39.83 - - [24/Mar/2015:00:02:33 -0700] "GET /robots.txt HTTP/1.1" 200 37 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
31.184.238.152 - - [24/Mar/2015:00:08:31 -0700] "GET /logs/access.log HTTP/1.1" 200 131954 "http://bmrocaltrol.forumcircle.com" "Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.16"
141.101.31.80 - - [24/Mar/2015:00:10:44 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Opera/9.80 (Windows NT 6.1; U; YB/3.5.1; ru) Presto/2.6.30 Version/10.63"
141.101.31.80 - - [24/Mar/2015:00:10:45 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Opera/9.80 (Windows NT 6.1; U; YB/3.5.1; ru) Presto/2.6.30 Version/10.63"
141.101.31.80 - - [24/Mar/2015:00:10:45 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19 CoolNovo/2.0.3.55"
141.101.31.80 - - [24/Mar/2015:00:10:46 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.152 Safari/535.19 CoolNovo/2.0.3.55"
141.101.31.80 - - [24/Mar/2015:00:10:46 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Opera/9.80 (Windows NT 6.1; MRA 6.0 (build 5970)) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [24/Mar/2015:00:10:46 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Opera/9.80 (Windows NT 6.1; MRA 6.0 (build 5970)) Presto/2.12.388 Version/12.11"
192.3.34.98 - - [24/Mar/2015:00:16:15 -0700] "GET /logs/access_130709.log HTTP/1.1" 404 89 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
192.3.34.98 - - [24/Mar/2015:00:16:15 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
192.3.34.98 - - [24/Mar/2015:00:16:16 -0700] "GET /oldIndex.html HTTP/1.1" 200 2380 "http://redlug.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
213.87.123.62 - - [24/Mar/2015:00:16:31 -0700] "GET /logs/access.log HTTP/1.1" 200 14058 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
213.85.255.195 - - [24/Mar/2015:00:16:46 -0700] "GET /l?Y=ERK0k1yHExA4XCIOa0Q7tacyAJ6hyu/k6tLlG5AqhsV2TSm37XOMNOwZr24XR/O3yhJYkYAJ8Kq9EpIXz46M6aqYGx6o0ZPxCrfwfnE+5IoNYurhbvts9OPTWUZ70XntgHNJJnsQ8UV5B5VuTnvX4IJPm6RpjWAaMjiI84QD5dkCRycate7EtYoGbxNDce81mUWIYWTzQzHWZOcL1ODltRZxlx8fcweViq+hlr/qR7GEVmYRBZg/jYsdnAuCUWqNjw4CkeqALyimwrxBrK/J5xHfMXrBgG5M9myH71HU+d9A/ZS7E49dLa8DlyQ4uEezsgpwL4ry7/mNpCDtbpjFCPhtPGzfrW9nRasWTCdAspoHbw/4U8Wn+fkuBSxu7/MQg78JqqU1P9bs8bpNjkS2as6tOuqeU0H6EFoTumU57utSTDsCkb4NcDYpRz4T93yTyonsPYHyltoCQ2DeWjYCCwJK6IvF7gBg66ZOlUn4Kc5FwICGOwyPA7Qmk9WAaF81QLe+RC3piFX7HZ90lWaYoDeGk01ax5d+CXHrEj/u4c3hMMt/p4USQ4zg9cBaYp6ydS6k1GYhOi/RGVCYRWw7UdWM8uIdkNJN23EmWJiSWialg9REDRpXNbNBNSUhLdn08pEi7ojtAdK95HmvLrtwmbXZfmSe43hmFmYyGP+GJxpVBC2+uSIHsu2uZ5xZgiOXpuqTEHUJFuf72nue2Bpbxewn1h0f51yg8S4D8B0gm9apJ9A0RGzYeXcif2EyKqwrjQs2Dy4nbBjVC3xPQoUE+Z8kd28Satrmq4aj7UfCydavjxG6dYaVcY HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:48 -0700] "GET /u?c=109xBRd2gePrdYC+IS0aYqE7kWkryjvEBcyxkM41M2Fr2DvsRgVFDk0//ivekCX9cUj4PCd9PfFzgMFjBcSskwRiZLAd4CL5kK9AUDogNOtyrtENLTDnKBIurRs5x5qKVcYtoWHzQZ2ENMBi4Ep9sJOkTebScogRgDTqJ/4dw9BAmkuc25iJ49InDob53g2RdvsDTn9WFTYAk5FPy4JTtt260kHuP/nY+45IREHlqZtV79HtOdwAELwrF07z0sfkUnp4jo8QA+RWEvUVSUFy6qB3duRHisEmnE3nOqhmTSgx68cum2ZpP6ey11U+lpVwvaW5Hf5t2kinaoWFuYtF3uXl8DqnGditZ/NwKq4DQXuGvsm5mNN/jhZ7rvDrEZ7wvK89iDg6tJCdHZwrw/pb2Zmjsw++Nm/L0bEyxFWD0VAOUISvA768iJ9xNm/m/82/11KIIvzLzCb/Ye3y/xIYPyRcs+h62BleSkSfPmIeMDgOOAyl1aNH1226A3wtV9bPRg+saIr4Dvdq/dcbT2qH24MOOeVUFMgR2DDRirinS8x5ylZXvqBkSm2o7WsN4lDA720PFPc6Q2lJ9Q2+afB0xf1+WSgOlhLnnz32vYvqBfL78qpiocmZzLPIoLuQ3kB9AwdWX6UlWrQkJVD3oNLaHWwQlatw6SGZGVFRw9LeCLqiSlv/VCEhGz3qnIuy4vEcDFrNL62Y1Rcuu1PqRRRNNnuXUNwmzCUup+VgZPxrub5p7lDYvnlZSbZrGiLJ4LqrFdNOwhVo2HRQ7HbDFwaLHFuuafCblUNJ1DsCMZDNCulr1UJz2i/hgPnTaAP7Qy9b HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:50 -0700] "GET /y?h=lre9r0quWY1l+/eCR5IJtma2NnM7oGSspy7R8qYlysDygLbilClzB2hHg0TdOUTYGdv8FquY2TysZHQwhcblYhtjSo3P+WvIRy1RBsvUsJ1A6/CKKybYfOFmtTmqQGep2SuE+jqYXExAihP0hqnyphYnLvahZM7++VXm52bcbiklAlkofcQbniF88IgyyHx4sO6Gc7mOqHe78eeQX2QG18Et6uQQCNBxZBa5AxBcVaBGj40LnAV3ncjzyZyFVNJt2xtZewl8ZgvOkaktBKmFMY6xfF6R2ASzudF/1hzcSQRdoqN404rb3dcHmF8IB+ztHX9fQrcsXc2fh0Fr+cTazx1FBW6Syfasr1Lt3iu2vL1F4h6KM2Md7YdIbO58qf0QqWUmgTxGCU4CRDuRmmghmv5SPoXSUPnxUCeO/YVvJ7vrKniVEvfXlPiEKiiKtjPhhRetFwWGztRQXS/pzCHXRJQopyvGE46aXUdmVM9DPAhLzdtS5NwK0n0CFs/oI9aE5lysWLOq2Oc2k2YOYX0Tr34OAGNeCLQbLkjVCFJGLWnBPaQCvNozxdyTUPtFOo58GTcV19V6YaiuR61YlrX7UXtf71U7NGBchk23FTpYm3CC6us1+uPC1UUq64XMYDRygzHEzKYMmrYuCjdNgcwuyPoMQKx4Oc0Eigi2ZGZim6lCIJAsYl3/RSuCfYpBLVmwSr2eT9SZGfU7vV7MwHwN5vhn1FWKiQN5fVcMV/0q54UQkhhpDW0K+IG+3BnyKrU0+RPa2+fzG6kzX9udxD6Lm9ePm/OU39choScqivldO2y8ctf HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:52 -0700] "GET /e?U=uPHjIxC0X8r/lk2NCEn1IIZB2aoL/Av7jmK+H7yFPntHI7yu4m/reaGCelwMWDmMry43tYSzQE49v8w4ee5RbAGBz1yksOMhAe59yVxN5ojH/G0CBHvtaCCoWizohVAyl6b394JgWYJW0cLpHWmwO/gYdj2E+rqe+v7WaiJ9MCTgIlkthBiHdanPIbxFwDT5fcz3Hoqe+5FbEABhlz1ngm+AxhtMtFzI4Nm10Zb8ppb4MOfP/TdwIdvcvlGJQucZllf/oZJ12sEWXxwXOREpMzcqmz6pdcO07FInR0i6YLKfV4rME2briWrlvpfOIpeZFx/c7rtpkracL5BDeb30jsA4JZitams5ZrJjduGhRIDYRjG5XC0o9zLExfT1fUOMpElGSt6IH2d3+Pdd20WuqTFQXhMcGXZ14Eu4y+djDZyTSNBXmw0QD7si0uS4n2sTOrtxTCtImTFAaKhZm9BvkExIbz9iOkluLFujsXCDSh6mk56dfKkOHbOAUWUq7/REN7JKDdx93dR0sTocb9f9swKUUlDd6a4YtlpihdB7BlQyyksh3I/mooypnIlERS447W2PankjsJLmptGOxCr8cdsv0zq1C0bqMQFB0s4qHZ6AxnHYzD2hC+IX5SHpuLn1bikHxTZrCkSW9wcbeKdbkZbXqHb2Rv/HjG3ocnGaGOmUqpHulpxvbpZd4emSpa5VeTwEq2YGrPljR1fR66oUE/4AA9sS2N5VmeoUYuA6DxKcNkcQ3EmFaTwivwwjUpOH8grsp8hZGTpiqaIlEzb2WTDZDhh8bSEgQg74R HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:54 -0700] "GET /a?R=J2Z3UO55Yfzfnf5NDCMBTOIj5Tl8a/GTDwr7KzMxIZFyHAdalVCByhLPdF8e2knOXkUkxtuwd03kDeTqqxRjIEg8Mdx3emBxl9HA3mAStpuUkVprxqAQuMbMyjf2eQ2aXiZSj3pbiCbKJ8YAjxvt5OlsbWfKp27GamJ33TXE46eTeidb5QZkUdSfSpR2cjZfcTViy2OreiIX0yKamAt1mW54XYKl7O/mJWIBsJEiv8zAp5vgWkd+YgBZfRrfPQ7Ym9Y57CcXrm/ACxjNSWZmP5jI8pH9GsCPnmJtUvvBkbU+cDK87DQunm+whrjb71CuYNi/OkkwsaR3xe7n+5BAXfsUeWmyOI6k9t77st/9AW/ScV2THGN3PqvCemgiqwgXl+1i9Y2zMszK8m8/nO1dicv7t4wrSKuIC3taStm2FlHfhtigWYwp6I5UIQAud+OkvrHXG1XZ6b0fBldR0H4BVbbRP0uxvFc1vIiwyGFmyUxTOvEFPQXBiBZi4GRmTpzVZDLdeVkl7M9XDldpfOe168PxOypSh2xORrjCD6FVd2esUKWCzyLsLn03SDvelh6TZX0xTvFjiqMWnWPn4M5W0eNNHhz06V45DXGrR6hQvwE7AXSNw07+F2bDLsIJS8ZMiDzkzeWRi93L3gknZsY92AvrnDD52e7PmwKSGe8z8mwpTI5AAJahuANwjfT8DBUdr0Dw1ai+2e4c52D9tyfRXbEPNUVb8j+1QJTAHX5o7zQr2R7edpBlnikorKdagWzPJ16iG96Q8a8K5+0b5Tz6Ikt6pDWxvRZOfewYotxiNpGRwShlSKz+2U18wX4nUZVejSdnzszwOSfzStPoegkN HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:55 -0700] "GET /R?D=F0KdDUObaHt2N5TW+ACo44GEIdwFJsRadrzkXP/76VXxcKCTykJqjZEHHUy3x+aSxLAM8D8mUzkma7sy5VfrdwCBmQaO19QeddZu+fHm8BzF/jO+XOs0SRM4kawqbbTqfPtJgcouXEkSlhqiL+BMjQn4c+OWWhEa9zu8BzyLR/FSAp/rFJkdJzZOKet6uxwKzuTNs6tAkaKB4U0CE/eGHqzNV8jvzPa45LkpQPQ5IFol7f8CBvszVj/iKla2R/8l6xmggbh2ldJ2xMY7i94HclWo3X43kWnJ2LPuabJWBX+WQ5Uam5dLnYDnjlZ4SuaRbwJhvWEgSpxgqHnbO6pFDHy/W0Bju//TU+E3YYzOUUsT+pjGtCwH+4oMVnXKQcIhshmVjklvVdlgwfhPZwtTZrJD1YbZtJAn307iQ60cHXsFgxVSSrLlISP9sjyTaliv/gozDVRx8fiUguwqyLexPD+t94EaHpMAJCggN2hryiMJB0HzfbunFU3t/XwHefgRVHVErhMkWG08G/iPlLvph3zDDak3mw6qhr2DoAPdge01Hq/5uYM4DE5BadbTMKr7+P3AQRWsr4y4vYgvzfrt8tKzA8Mc58cJMq9xtU2L2dfe1/Pb+295NnedCOd7lBmdfh9m9gPEvx3jwaS2QA/gCEHHQz3fIPnxrLZqfjcJMcsXLrgGyeYNO07TANg2I5EXBRGVRCb0APjQJRemDeZdhz+U/9n0LZqlgdgdT9VxIJTYSl+hHz9F+cUccTC7shfDvqA3rXBgmFBV/GT7UOjZ/XoVvhNSMMi0k5c2esJFU7gUca+psX7my HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:56 -0700] "GET /R?K=/1sqcmUG6yqtOIwkZygClx9aQAIbDvDH+baxBG1PjVW7lzETkzeBEyXJBJRWA6aQye/74F2sgYdblFqDg/cImiPOboKOxziV34vmzmTbAgjuqYxiY+XhVJJAdXwEco9wRKwha93UpAleEDDYqx/ufXEhVsLltAd7SEaX6GVoNDjL64MhL88oKTV76tfEmtdtsjGhq+I6usPY0Xu4LWzUgLNDsivmD7UL6sm/yjQvidGOAcpy//GSdVvSZBlFrP9baFFKpwWRI2SEEkOqb1OHQcOfrStDwqLcvdNA1sReiDCIpsdRrxGah+kbyGdpIW50Fh8nS0TVAeja/CLaQOKz3ardemutWfOpVOWtJB17b2HrzyzfglN7vt6sM8BVtHozRzhZkcmgtQ1StOJBJhFySkpItsNJqJBeljU+UtB77GOKj3Lb0G8Yn0DfgnXpwxO2skRimTVeBEgClFGIewKJgZlyoWZvrbH+cSYdtK8sZxNdGJ7OoX0EqFS5p62fEzBznCB5LYoURbSabg/bb40TL26GG9mlX4N1u6KSImtGdC0ZOFQeufbQzoz2iCuvMg4VkpvkrsqhrddyBxGgJGJzXq0UElW6HgdrFFM3BZFFyzFcRJ6pr4XsJXMWH1ixb7YzxlmULMkTYCtqPloc3sh6R70ukTkAO1MBTsR+ukEN4glxWfklg+J0CBF45sF1YQvIjJH/mvLMPkKTqnmxRcwTp191Y42wyA2430lULXK3VhBaMaA7BvdlVlrndcpM0E/YGWNM2nSstpq5orlqxYs3o2Oo0zBjYIAIlGvR2G5G94J8zKp3cAIOp39s85aPCJIV/3+ZpRqaaJqdJWI5tqlX8iOkE HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:16:59 -0700] "GET /C?Y=nvF7XGzTwFatCZRakcw/CypRoyS8IElRvD59YabhsKFE4f47Z5S1AgvI0DyUoT7n2NyGGVyJA71ert+PeiqUI8KJ2+UFvnc1dMvYWHPSesiWaIJhPTBfSPbSUUcnRZwR8AgAME158889fFjf8hrZ1hwu/CNJ1xu4KWboWpKbCK+3s02aIea2iNEohHMs1rdc/J86L70Ja4xVREEIGKVcjMWdcZ5rEpD4IArHdXDo7pIJBphXyrX3R1QZC/MWlRd6ipaQT28ERZ3xm8dND4Ahi+e8uw6PdGRNDytp2rpYP4lLEEpPM5wb5N1T9awuTURDFtsaUS7LvDKFKgswUpmLieBY21+wIAx1FJ87iPjwRiqOW2DdazfmY+5sIULIUSAWKKir7JszHZxLHrF/Su+7YgQOVDAfg7Xj/RovET1FwP/EGkfMuTe6gb7lWoF3gPhf18+ELFR0eHUO57D7Bn7oFDZoNPUt0p5+2bFXZQtWCMv+ETouUS7CbL8QBOujpJ/VtUTuCE1SNrBaO3900cT6xQoD2mErMzxGo6jz2nXHojOZVqD2U6NR3wO4mX9GULAXq3NUt1zkWrsPm8rFuT+xL2Jhdmkxoacih6uLsnPFkHmWRrw+kIDvyDFNvoWMWdTQAr1bBz0jYxB41U/nbUiDzdEbteoWQ4XKgSESjwtOf0pjTGrvxyeqBBD37LXpJmEyGcaMESKpnlQqQM2vqGgIXv8Le8BOOVlKLV7nW/ThqO9GrKMvafUhSJg0ruB1lgczkmBo/m9uTkzBd211NYjnEZ+ePAEpZR66 HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:01 -0700] "GET /I?x=zuJIuQMnFUu9im9T0dJHyCNWN9IZeGIzlYM9DWvxa27ktCXUghw7ftE60vr0H9OyfPqFvPTROspvypZNpXwCSLz15OCu1ZbeQA7XILMm3dLn8awsWqSdmL32AZFUHykUKmxxN4l5+Dc0+VR69MjRPjn37DrfMGdYiUbz59OgenXFaqq0Z/lB3hJjCN9VLQ2W6ppJvMuQN3u+VFOFNpPPSz0zioEMBWbMfFwVdo0vRRatKNK0OKhW8PWdqGm9EI1KK+wcm3+XPaPClB5v4TP5oWK04Fv2EeSmBqUUtRFshhe7zLbIVhNVyNdkWC9X0l4GhcH017Kd2CZaV8AOmXchXcSloVMd93ub1JZ6gF5SqHQwpH3pfzhdWpZ/Qilf+YQsgvm6cldRoMu9KQLIAE/SlFPs1tTQ+C4mp/6fDHeiidCSK4m/xfmQwshNtk0arjo5+mFzfnERUqjuTHhWu21WCDXdUXUazqkXbQco+lryYg6Ur5cjvg/4nXORnAeO2+W3mG15+3vcbREK0Uv2BLAMieSTsNgPgqBGep7LSec1N5Ftap8jqfe4u5vcAEihL1GfYBFvF/rROxTPcj18mYh8Ftluc+PDcVgbS17Zfx7lLiBnOA5Gw3/vEk6cbZ/9cv0hQsFxL8kYvvKjv3S3ZpYSSOzOUisPwChTTKjHex14IaYt1pEmSDWW0AXi0fbFQwRZQYJOOjP75jrq53ZwrbBnPILxF1vQYpykeHIDVMGHTV9z1Yf6Rm85mX9sdutjRNlROfbF5lVGid3RfowGvkbmLz8pRM/qKD1GfUdKFFD6fcUlH39asIavKhi3MYLCMxBUVHHjM4ICn2bcUZDnWV5qp HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:03 -0700] "GET /K?A=EfjTpJrw5vSEdbfXjQ6/VJCaMhyzGzP7IdGx30vp45ha9HNeXf8VsoM7IXGuYsRmxsEfy6J1jL/NeljnTwy4c19RxAyXMHQPpJpx7V6R51nnn0EELiqEwQjMXsF6GQXko8nPLI979J/h4nT7wu0Dm5gsFUJ+Mae4rIYRTAtszHPXOH7OqAmNilsYuZyqNd9fHynu0/DfWbu2g3iR8KEYx2z+3Cr0ARlHzsbw9Ioed+HyR7tofL2B0RCW5DqGfctq27RxZQYfAs/+i8/GsxJfh3wYsJwyj07ehXJ17O+XSZcJHJx2EHCtoCaRvy21WnbyL//ZKNtk950631x7oBpDeVrv8cAnX1756VetuMgnIY4pj3f1vCJlMon6mvcA15qbD7oXjV7V7AY6bBZDVkRZQ5SfL/7crIviC2KCXPNL7tdBUQkBcdSSc9vh1QVD/lzMNxY9kzWGLhbS3xfCQLnMoUIh712qBKpO1Fpb4ODlOfxbWlaIXmUvmf7PgUTPN5qF0iGCeIF4GYf/v7TePQhJcHyi/T2y9a04/ZueNMmMBPtWCZhthqOJVr7Sl27fDLvuUeDV93TvGGeDkOsq31Kt3yN9hzk3csNQOtwH2/HllaS0httCyXrLZWWYricJXjZY09IRNz9Q1CAH5b8xBnuMv2iyDEif8nO10KePwd2wOHc9zFCsqIwdANKjQoPYXCVOG5QvzMr2GiNRm1n6g+3xrRVCxNeQfkCFlQJeXLrKGhu6+1nUO4HEBjk1VVGD+cyzQAlotwHxjKdLOnSmpM3jnDb1KTYWGrT/rtpK7Hm/N0fmiL44xwgERwSgRdGFtE9jPTOyfvfHxVQNZneUMEobmWcr HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:04 -0700] "GET /v?n=LQLeG8TfUwjkZGXP/6hXwHYCiqAjBgUxsAIqftAqbgrDs+aYjiabH2i7FGG7lNC2CfAhszvN/yYkCIOPWLPwzPbFyRHjWIQedew5hUKxDA11rtLL+s/v8bqSQy73ogI2UiAxbmR9vEHE8dc0jXyimgZEmQEHoFFJOuyjkZ8ogDFoKzmCFrDEVo+/X5inhZB69Tj606wVTZnqbEoxja+sg/aw8iN84LX9FflqhE5FGryeXFt2BKwJxdJhZD9ps64hBbfHYtfrXTCXoucffo69bXoqGWCKJIR+uHGphK/snnAGf9608eQnaL2U6MrkfZKK3vvhiMXsRBYwu+wqAVSTrb4K9GDTyhOFKs738Mp8S2/UdJAkK+RdCmPazDJwhSJtdwLYK0Ox5bRa8kYZWGRbmsc2aMTzDEnG/y5G6i/r2TLWZyZdXYY2t1X0KxNjkSsFQMfAvubGbVhST4pw7RvkS9huK1oV4DClTL8oxJ1+/gFNxgMzjvTXJXwpsFozB9qA87Bne+iDVWJuZS3PIJYlX95kBCQ70FFHMqjiox8zjkv7Xs1SFUaSwYABsb+4bXDQ99krWMVTwdicR2ssNlXdgmU1A0p86sHreslhr7o4r25ttOpOrVn4uJhV38mMbBChMk0F59Kq34/77+hbPYAHNH94q22wgBwpHAnMNpzeYjVw7sYCLT+i5dNUuVnAyfj6zcYgeseY8wDa374etLnmUjRlygweGrbEFhFKsD/EboqldQs22RYti80aMxrEeO4JTE6kV2MUuPQybt2QY5QCqLK6qiZomrnZC1WnWD9wkxevNarGVZiSh+/Sl+d4t+UG3mKED/2RX8sd/ HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:07 -0700] "GET /g?e=ZS8Y8m87zNLEOsg3nJjUhBiJCcg7hk4WkcpRI7VBTTJh0ocU1af7gTq4y6rau9D7nFwsIR/wmPc9P3yyCCrDM8pddkpKrtyxYmirE7XOGWZilgoh4S0RzL7GqCH+oQFeiYiOa8o1vHK0yC7jXmLadCtKoe6rkki8BN3iy5m2POjCoEkrGBh2Wp8U2flz17XU3yoMaXhhNs4DV6sjyzz0gwftukNciZC0MeJ7EV/Tl7CuOxXZBKmSqZkNQG38Cu/2Hkp7+Q5FO/Dw+ORTUiwMZ95B3fzoYVwF8gBmepExkL4bEOqpKBzHsdsrTbA2te2HPKDNd8JitdIOFSuzJu+/i6SlfEGBWTGQ+Je+2ITipgDj1aCI6bbYVOq5RtlQBhbSV47R0vq4HvM+ITAXS70Pxgz60tYiepdMICRGsJC85bDnpff9EAzFE+ut1mnFE+VDkgW8s98TfYXYK+D9rELgJ30yBuLz4aClXqjiagbxSg5M01buU9oKbs4jR21rXduWWQ+ePtYPd3GFvw1yizLmesrFhajDY0PdwFUXtnZnF7MOaeH+6j1mTceIMz4sfyDOSBJ9UgOhREpPZeoUfzgdDN9E/Kt9sCHLjceZsoAPxh15vWfByLLEz7jR2/OsAMmkFUDGfJOKV/lyeML5QKpR1OChUIs9uECApqZ1hUeaNy3KKmXIFSi/CsZgla+wGL+SPJQ0KLfapu74Yggpz2KjV8Dx2ORXCkhvosXG9VLSPyN2f/J+PbxMV3LAy/hmtZB6FPZFfHfk9PciUiqQB8+5kfEtcEaZZZ2BFRpNUT HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:08 -0700] "GET /b?a=SOnCdD+TUm0eiiNz5tcJwlv4QC/5J+TyAmRaC2ItNQ6U1891vlS2aDiVtxWaw+FayBk7XSdP+lLaLErGaubyxsMj6cGdUtSDDmbSypm6pnEXper3l71LFBtO9Z9EA+rys7jDumi348b+gz/GMXESPq4ua9oije3lZMnvYZIbcazwXvnr4TSwMdseW+pCigGSmajlD7tq06kASBKfNf2T6Fe9P+H91xS3Ps7TVGlDSHZHYEfmRdSqrtVsmBksQoOpyodZbvqSv4e7Fm9aCmvURzEFKb5Md4WbgoRrG4uRmS+N3DxAIxPkWFgRaI2DJ647j8lU/728OTOfhGppldcwByqoPgnQy1sX5LKwkCwR5QdrWEcaxsJIiHT10H5PlbC0AQRuCIS2DpYp+cybR9KhLo/h0WhXOCjgWTPOgk0CYOo4t1mOFuFsp6NMFEpOr9WpZeSNDLDmiIzWwpGM2Op9lCYE6i86nhuxVrAaxz2tBtdzsiU+2Lm7tvqbPJEhHxou6yYOevQPzZSuWIodWNIsd6ozYhcqxX4AXtl1kEZbvQ7ECo5Mzlz/3dmskCTEsNbiZlEtYnyL7sMTBD3OwMF9UZNN+yCBC4oQK4TWGWVkGbgDNJaAbB2ezChREDb9UaaFisFmnq1ndFgI7OUvHq0UVnZ72ZhqBiTyhC83RGGAM+46Ea24AP4ktaE5odkHR1GGh/vKr03CTtrPvd+lYMy7RBC7apOU+qpERDjOQ/kMpUZjvGGBPUUpg6D/NQjGdsQ5DZUg1EuVdXXG1YH7lAINVKoz3S+up3O HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:10 -0700] "GET /B?v=odvPHPfL2rs0SLJnrft9HnkY2QCIohXnZ6QQYrTSI45WpxMCt6/xdaDaAAk192V+3Cexl1y7b7W/xKPt7TUUOmHbyvx7FgjN/mtUWRUFbUy4RBWAO4RuSloiwWtJWJVV3GOqemtk6sDWSe+YR+nHKwu4L/SCwPhWiR4/3mGSP3poGelN4ksNn+kSl+S+up+1pJqdAR2LkVr34UcuYaLaNeSEyZn1iei2FmzYjlWO2p7yZ6s0FGvhryunl4B/+lT9hid0fJoIxSSXzJ5V4wRrcny3tsDq47JVxV0m9aQOYd0QTdgyGiezRDxRBN+RWsVMKpFdJVryyO+RQVH352yCe+eRfZmY1McZp7Sev8E82GRGFFCPrhRtwk5WIC4FzGGn3pAUDRuU9+uWpMPR76Uh2mSmr2HHLyoGE0kzKLelGhtjEIKXIk2ces/8/afQRrNQAWDJKMD/y0VTLAxFofZuRHJpbvWvQTiUT3jPs83m/fzSyrTQv490M+LkWH8bje0DdqzQ1mnVk4feyNI5dmCwXSl033cqJAMU6Va66PBiMcMCFHD9qT8CGR+UjSqW5fMVyDe4sSUsOdgR/MgHhTPwLB+zHLCjrqg5UkCBFD+129hKgp/Rlq3M1Y6Sj+Vj1Q/yazgjgB00YS7pISQYCGgcdpX1JZK2I0V33DEA9/uLGgsE3NFGRjmAWUVP+kZPno8UbnWMcZKFIxgxrIZxF703MsN06tmjrc6Vi8DoK7uj9pUg8b83e3P8bK7hKPO26tPsphbLtAqQpGa3wVP4sUIiLWAPkz1znbWouTx1FfW0DWB+BC+WGc+HHlmE/i HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:12 -0700] "GET /E?t=K8WsyDTlk+0i7YSjKCTD90NwPeyCtnd9+fIIOuSe3TIZwK82AVUUwuwXdHaMvohQYMdxB+cxXa77NvhH6g2CzA6/F2/ReyBUUdv9u5fep3li5YbTy/72X/uEVFKDI5JgbJSJR2u9538e5PDoaoUjUxgPYEXPa04UrK5OmdpSZqQNPKLk2S5VfmYzTb2DNNzdnPZymmD8xaU0w0reO2Ckjtc++mcAZ0t/rFCB5mz0K90BH4vaSVOabMNCtuMzGJiPiyx7k9661S66L0LcSvq/3yxu6rhcmYW7j0+6F4rqZpeQXEvwuf4fQJy/6BoNAzX9t5sNIdP8cXBzRx8E2R2ntqDFS3T2wJUkTqNW/BiuvWvwtC3/Ydtt2vpBB24x+26J5rTRFLRDO0Fr5MYUqhn1J5C9GzRJjoL1PXxI3CibB7o3CIFCNFqRWM7tuT6+ncWqvQAKfDKpzPdz2MVGRBSvVvCkEPii2PAXtEZ4C1xV/JFVlf0YhG1EnsTL1GulMxiaQw/Ijz5h9DygbQEHEXhH++S13um/+XJXP1W0f6p2qlWcfygMqA2EwNjf6F3ULYT5EtsbR+0hZDJXyYisg3HVBQmvBKU95WO3Vc6r9ycT0X/FKpEvQuG8JCkXUl0lAUcZdMNvMiMbFGTK/1SZBrzrHm06JpwfiOJb0SN5gywgt4CDRho+Ori8af3+bai3GCfZJJ39w9T1/Oh+ALwP+7nBby6LUX8/SYu1tZiiy54zx6jYoK81DaPQBwza7prA/gF9+MpDNbIDik/tsuqEXBpeW3E/hVB9z7lEsIOo6Tf8 HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:14 -0700] "GET /h?j=mht1ZW/YqNzM0eHzuh1F7XYd+clSC0f8FNt3YzzHxOBwIOuVfLEAPLhyk+pFMa/Y78VyIrRnPTKTWvx73aoSfP8eveD4F7/On/yfJl0B+viLbUWXPDPQadyYzGQKav1zYJ331ki/MWlDLuz0Sxbb1OjL41Plr3Cs9/OBM5ZplawbZABdLpaYzRr1HaIDBm/g8qfuR+TAPIGmwosZlImcKT2SbwAI+hh1mMh1ufOX1RN1bPmZGebgt0fmwIl3FYKoaOcNu2tVebQ0QkikKmq1OlCb3OIRs34vcu1ySGWK/BX3wSCNbvgH144tiHnjhmJLraAeFsvGPMWjzI5XTTPP6+KPLSz9uGs8rrCXrbrSXfu+RPTu3t8s1UMci4Q9EY+Bi/8deHgeY4KsTlKFOKAF7K4nrX6w2uWquDItFks7FNrZcid2xrEoKoth1XgD899ry6v/+n76kzHBInPVaHR46+dCZyxKIbt5Yz7qR4v1uEkRThZjY/foOycMfOhiM7jTf5N2qSGM0hAVvqk5R0WuMMIF2rVGGPSH6uNlr6YFTkjJlycve+0dfp7ypa6PO3KulKwzcmolUpFIJ6Fx4Njvmu+S7l5/ChwaedIEPiRZJCB5NnoC1WJgWlLziIrfh+GD0N3ZoMXkRKNtpFnN07st3c2X0N1rZEw20dYT+dlhCFv2+YaBRNKfmGW85aJ1eWWMNPNj8jwCoKFSGglrDP6J7/MeKOxvDBbiQ8hazGy1xAYmXGeszFrVA5XhMmkJllZeDaqbsyyPv2AhuqqX3YQ09r/QdCFWG0Hi4I8VAnFuecU HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:16 -0700] "GET /M?J=idGulraUzabYPMGwvKbXr3HsMWFGUCPIWtYhw/8mO83cGPI61JP2T4oCwuMPAk8iaEf4t7KXSVJUU/Gfyfp79U4JvlDQLuMtNSEbACZyXZITp7SiB0nE8geYP/K7ydAbSoyeQRc56+SjuJKVNhGYlKdvvBEJwrSoUjfursqc7r2CfXKcstGrLg/ndCt4teb1wiFhM7UOTYtB0RNClx8stZ4VO3JS2N2QD5PKCC6stcsyDoHYi1hHN4myKE0fWmxi2HvgRrGLI8VO0JW4onQ7dO2XGJNdlTelIkvGaCFjsgsTlFvnXfx2Qnlce3VNHs2iBbU0vORJKr7mORVDtVKcjsRZLU8x6cNijFyPTKVPqWOz2C6cFz3K4TGYFsOEyU9K2beUdPEoC3q92MOedhYOTNkvTtufRBxWjCJhmwgJ13Fvd34Xspp60FPlFcQKQAtzDvBNj2iHaRLX8ED0NHU/+oN1nPSd/ZKt6EX6K72J1KjH5mFOPi+teUKhZV1829jZ9PuUvzlzC0Yts4nCKhF5eWFdWFqwVg8Jm4pkZ/WoKszcPhTY7TrK8l1j8Fg9U13YeORj4LSD0QXsqaDhlFRtOwQYDbT/mtf89uYYBg1KCq3jD53M2N58TEiStAofazpPjeIkketjRZb4eGROofdHHctr0/oNcntxNG1BD/mNkeiKMbpwIFksIeLFDU5x7fvirhm7d+Rx2c3J4TZ41mAWSu8r/QumqfaGOnZcIzkkR70SZj5MtCJ6Xk4J/A72YcuZ93IWlMtKP83txlFVIfwUpvNe5/CKB/t HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:18 -0700] "GET /k?o=t74uSOTdxYAY7vOkh0JBI3RQNnoT1vCQmLFgdvkV2vjfHa1YI2XprUDQTZx96xE0ZtTawqncSqyPjdLZlNJkyEN7qGb5XIe+6uLpfPNtlpPbydyLg94y2Q2wkvA87AL/XGy0ezE00N9EzbDf08EQRrUPdaY85iMQjyPnl0IeyEQxJc2M1nEfrwuaFAhp+aCbTC//ns+7A0DosAsPgrhmbwqUgCTPTG5BbbCPtIg3lau+RG9SdR7+VizJfmkbdqN7pMy65Fs3Fl5wd7JyvlSGdYHF9voGCi80Iiv9pFUCthA+Unqfo+vzmjcv6Wa+fsrjuhHXlcTeuYmyXn4k3o1D1aepoAyUu8zKCEWZcD2Te4YXVkxq2wO4AT/khvJAL+ZMdd9CeI7V879ydWDKR6iUAYJgD0IQ9+oJWne8ZOW9q6rao9fx2JkTkO+ZGHLCoM8qp5ziWDKRlo6sUIxjddBUAbCrV33bGoEiXBBsw1y50u1s3iQBKGrxF1h1QyonM3XKxL6hfls/210KC8Kn85XIz3mEzu0d5yjlFxND1Oqwc9GI06BfFiLWX2D8ToSD8zsAVLRqukVxnAh9rWenMJeBeHzpjwPz3tSOmoqp3DJ5sVH3deQCmguQ+kECSKWMFensNQQEtRW6u3aASJzud28QyU+04993yUJt2WYa4+Ysn/r0k5jipvyaKWFVe2m18MbxWH7O4ibo5uHfz4Awu3xMafW8C54qhZz95zyG4sWh7S9Dm+2la1pRVYxN7VfP+ZKdNbwgi6S5L4PBQq+Ou0hFtOC5DAkQyI19JqqyrtIFyWmmX HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:19 -0700] "GET /X?c=ycFuznLMGvNy9jeMIdcseC+NU2indp4CgnecraD6waCUSQisG3I+rEjAp1IpO4ItgXom9vaqjGT3okYo59h2GDuKXvR7tSpdsjCriZicwcBpDTOu/yGZ4sq0wr7+6KvlaVdE9Sc4y+Xfagrt82GCRkuVdwQoIJ2rRIq5RgZZlF7vsocGSr+lHDY0xHQ5mxyuIJgOFvIAaqogayQ+F+wK69pcVAWCGpQFnTm5PNT8yUXpijbmSrtQqeHsIj+a8foDzNTVF2KqVRTqfJ4G9IwT2WeCWWHsfX4sx2k7fGv65i2ZB8EzFe5D2S41R3EeQVTrzjCChtpzpgWPLE5meAwrMAvlQTog5uQGhHNyY/Kqec2iHwV9uOmVSjZJ2aebF+SVK01kGnZufFgkB6wVE5MQ644OWdEo+2k2pKBBm9KbJcFzThyFbCnC1+sbXZoiRXYn3pQy6CmK7AY43Tqzx2QYMbsMFZpmhpgmWylRBUqq6HQAgIwrkHbG2x0pB6GZb/NT3SGvCOqW6zlkL6vbSBZEPS4wKZujdGrZclS3ZLYSMt1MAWFgs9NRP3etfjSpo+l9rbKU4rK9a2cG7CWYVosI1HRLniBvy9Pi+g+brg3NOcyQBZC7lChBLCota0WAMaAeMRvWEt1CDGoJR0UaA+sidQQEnAVq7NUTc8AHNTEEv0yEhc3PfT3el2ddmtBCFvvY7zPiYMhXm2n5Xqo/3wvQm2a0YZrEkxlRCif8r3Ba6XAiMby8/DjhBJG3hsq1e6h7lW6rwDSBTIQvet0uFKVwyJDUwdvWbzVVFNqDdhB/PTbY2uc912aDuwoLSFAK HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:21 -0700] "GET /z?P=zg9l5hvc9REHxPeUWdpuO/Qfou4owR0sCs/L+YV+wuExOIcWpyw3IhSXV8K3nZD+nARFzszPLaVm8SQ4mqvt5JOJnLM8gZd7h2up//eyvVVg7B61TnHM55ywglutii/m0E1Fq63jagSCHVy11uDFyC0M4+O4WrDtCwgYqBQIAZrkV/VtkxlSAWP5SgP/QiAgzdwk6zZrwHaEjeUQu3b1rEabONz08+KFeb18kg03DNBCbgLhJCygAUIfT1Q3Qr0QyWz3oxN3g+jFZm9feWe+ZXo9e8daFpHWXnBtNsW8pWssqKFaGc3BMrFoU8BATwNGsiv8O+8AeSIDSCFNf7rRfA+97qJiAQ56wWqj9eY89cEHtzbPMH/ajHhCNfft0tyiI2H7XuRzBlBP22ESfdQ5spmWOduEa9Hj0OrJkD4nC5LBPHpWr9rd4EDj092h8n0a/WeNUVsuJ1O10v/DYUIqUPBrwQSr4mMw6AHlHDWvYmKFdMXYosO+Cm8Mc22Ict6ll7vAJUoBMdQpAdje20dd92rJTceijAjCOXzICfl5/PUOXa3XigVbj5Czg9lFm2hr4B7kC5ao6O4rxvcqOU7w8i+sHtdGz3hX0o9bohFa3/vGSAypFFyiN3hwk+mheQ3jFFCaBUZoW18oZsieWHhtbeHeD4UFztxrsauVYau5ab1KtsqgjMhoTXphWC3TUc23h//Fx+WQMZgu6AUeI+J5Dpt73W71rXV44J1EGq5vziKwZq6lqGJ2uEgkmOMjGSo5+mfOORp5oaCNVM2BJXXX5NQquoP7KZVVR4/2g9aYTX3orDUumZvHbJ0IsENTw3OlISy0bCw3 HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:24 -0700] "GET /m?t=Berf655sWQS3YzyBNLboQbxjpacmuvMk6CaCTZIvAKBzp+pRDDTxuVIVvxxMA7NEtjYJSFWOWW7KaZIklSvYnXqt4e02aHo62ge7orsK/n/9Fyf2hrGOrZ+eiBdyPLEcTCxTERClsHlTwKBWkT/WyK1xPfGwtK3IvS/3cLEQtLsZ0+u1IiC+EJ5fCuHcxmSrKpYW57ZNm7f1B+TLjwv9jdpdW6Nhp4s7HWaz2RlAetc7NyP06LSNmNiFDvaPxfrUFSJQTVvQOpyNiTahCaf+eqMDVHyubipaCWCssNj9cCTE2bMLPArWQ0sSvM3UyANHkbpADNYoHyAgCU1SlGoYIHJjM/3sUoThRBu01MlA04mpIxO4/Tfp+UMyVI61MMWtUprhmbM5aaALuvL4dUoZ7bdRkb3zjEXoH25V3sTqdQ9rvKZxj7LwylN7xleLWI6T0MABAJSt1IKzg31kLXUrbXANkkdNOC/wWH6q2kQ+J7cWrnAwbQufxMLB1fFhsnRHUp65b7pNjN1uHUIJx8IVaioEe8vicNk/ZJEBpJMsuoX4/7Od4AG97vAH5lEEBSju2rU0BQyjVj8AWf4ghz/d6qh+azcwn7N6lhwWiPQkU3iqcxOVQNCeQh8UuX39yEXkdxnuvIcCkg57ndIQHEbortIViTWXVEnhMDTmeCUgFpVxrdzAXNcIXZreSjThWIZubtCIH28fR5ycMIo88mIqFMdRmESxOSfeNw83/6MqP2/H6/OSXoGvyNe486fkzoecvTa76iYAG/lJcumbHHT0bhr06tNwn6hRgi4KNqlLl3OEtNlueTd0XhQgN1XwlItycYLnNTZbLHxiRbwI1KZCJZ HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:26 -0700] "GET /O?Q=YyQypO+D3V1XweOWBZkojDmJUfpTE+MxVyCnnlvSpU1SyOSpimzKt2tgIZKJ68+CtqZrZWZJP2rwjd/aGqB/VIyXCDXj/pNg85DbXG37HZct7V+QYzCit5X2hhfbKXLyyiGJo/8xdXfnLj5EhXjCS7wBVCypBMNapC5zIvPuvpO2EePeeCwJuysZ7pzN+Cz/jtqzZJ2MwDmzFKFbNc/4x+d5O82+skyz/KQs3orGrZhIkdIZIyQ40Od9/HOHODhrZ5nDZovRjD2FNFoSlxWyptrlAWf1Yuy1s+ssjvwAwi3v5N38EguuyoSEj7fNHZSigjlcOVSBASj1/Ty5YH0Qdz6YQdMXRWlM7p92sjwBU+xHzBEu5ZgmSsnvsdHUN1fvQY3apGOyQeY+NiO7sh4e0tiPA7jSti6/aUjdGE8OMeHlaBZ6u6FnwrDRSJZse+y8PT1loJ1hJtcMibg0vG/exafO2cH8PYjeKjq7NLVeS86maMYoIXdFHiekcrs4lNq4UaREqq8iSOipgREw/9rXqzZlQz/za6X9JTR2niZ5k9ip4rgeZOeMOBzj0tdKYygusoibDrBCAmvqqLhVElfkUOJwUq9QET/AsdtI9iurtHI1Gqu6mvjCLEXUb23AqYUN3xWeqQeeL/ejEJfQp9xWks7cZKRhl+yWu2q1Jom2lzy9PbXYqz7BauaM5mc9nREMUnQWWlIlFRN0CiGE7fhMDw7sGcTiDV8fISWIzn0wULWTY3XMW30LiipthkyQsuKF1gUX1H+Xu1Gk2xS2jLrQ3h9C0LRUtPYe7kNup5/XL5vN5Upn3mcp7RPvkUc8Sz+JfR9lTd2zlvKuUOpni9XoPAvv HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:26 -0700] "GET /B?E=ZYOHTsAMB+KoE7I9eBc86NrwG3uGAtM/b63C04aGbRzVEvr9wirb2g+pSwI5yPnsAgWHzNOXGPGRm/uaYtae+d50DBaB14ID/sWdi4EqSJP7rkf1Tr28wV9ENwcYkZ3iwpl2FygS1vkoTwUW9eaxaQieMmt4olIYye4pH+N5aGfquqJkkReCcNHaR91D8LaLg2Tx20eQ1QYPqDglvKbceeThrpxj6Dl/BQTzQb40fmSOFXp+p/OI/p/1Ieb3lyVEMTW/x2OoWfrXCucLtMmVXXFHOftdIxcZnTGPCM1gYpIEfqbG4T4XVqST13WEh+GUnx87TKTuahiLFuJUTzSydpQ9gkgdNOolgTj7uhPbnWNHnxi6Ddspq7NP73Le90rFmL+moPkX00ZpgHRKYNaJ19aal+6leVE3atxVecB3h2eDebab32e2MdUswzIiQF1Rvw3Iuycz0iPHxN6LQ5qQTusBTYTi1nEZqZDOzT4jB/iMEZ3xtyZABuj77rAmyl6bGBYBxGeODsLqVnnulvzRtcUwLA7wm37hmKbIt3U4hdNUPD7An2tcHf7AXuQdlfb3yw69R5yx5f8CueAWYK3ZtN9r4vNLXGUbNS6FRjjWo1muX0os2dXzuSwEC+KTSqK9iBZwZypuiONtjiIsjMuGbtIewaqmyuTa0ORq0uc/bPe+vR2YKf1z6Aj111it59glfRuzgimbY0RgAiMJkiixRx8vdiZqGqqnZ8xld2sKBQcVwujevy1dH+zJ5geInd/5FK0CtrEApuwfvknew+qKE0qrkqdll3Pv9bDeTDeQNrpmKF+6lIAUfi HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:28 -0700] "GET /B?w=cIQGi5aqe1msapzoDZRgYRDvSjaRh/l+x2F+C7wEOIUuVkt/+w0h6ISZf9byI078PQu6vY39hbFCKTJCJeMLJacEqHSmcUp/7iQGgkHQTt9e06O7rZgTgzD1afRlmvAIcS3dut/r9LyztkR22PcAi1VS5bkr3AqbZvqIEqy/NtyZR8Kd7Oz24+53ovr9aebEAXRvhoLFAZ/R4MeU0yyVSgP5burkTGn0CaiEAs3iP2nSaTvQT8phHFyxjInn0IOBYJLvN/8ZDSs2QUu0CiJLYQ/+nGmvCe/sE5wboSWs5TGal1VbxjTD7XY3IYfExrV5oFchd9B5E4X0TGHruoLsOZFJopcN2B7oAAr8HuVaeL4OUGShqvPHCc9IAcWdZpATiA+g+U6wJOmiP41eI+Z/YmFX9n1GOXacSCZLDxQUh2O26ds9WTizXJJkQYghhZO7yv8A0YFrfIEpozcDtX+bLz43skJsSabe5bOyXzwDdh39z99GHUfMeFhRBOrKQzlbNdBrh7LWa4owng63q3qXJ4Sx7mJAospnlYmW5YlW1NhWfLAqtCtgxyniOZZGEVmgbJNIvbP+Zzq863xo5v4h09GJzb/CD/vQ4nQL2z6XtyIZGV4w1FUUj1qbgR0j3QyMWAyuhVSwoDA4LfFVK78QT3Bksn1nLvIQ8AWFbeGlTzNGkPMU58bec1xOvT+wMWtsOsUXvqd2HHf57HhBCMx1rNDE6d1L10ayKMZgHMdmPyjTjquE2LaSdukL8TkZIzCeYP9rvonE9lituOmJ9DA1tdIcUVKCBbM+dVojE9kSZaFD2/2jFAZ7GVaRXn5FxXvHZbF4YOcTnykPu14d+DWvNEZ5 HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:30 -0700] "GET /x?C=e1gbPALNJKk8Dg3bacpSlCWUYcST0vIKCdUrPCwiiqXjeE0eTs9p/LdmvpYKxoIus96Wmdm8oFN48eVtrXRNfN+ta+YyDKZ7FDpbfi9tQQ5k/H+9CeB7yWEZ9ecyDZud50H2xP1lwwzsKp8yPWSDz5oXDyUTO7fe/TKkqhD93Uy1yk5PAgM5upnhvItr7vsqpYX+t/nx84OTpinTBgZOtsMM19+J3KJF6MLqLA7OkL1kw6V+JvYZmQadzub3dzP9Ml5hC4T58h+0thyNtog9i4tUgNdUZ60HYe16HNL4MMX4kRp+XU00JwmRTHOZgBrhXlMqABlBLjdZ2nXMs73S3341xgJ73vq6luYdkRsSY3Lc/Lmu6MJszm3qRfecBhLVXKF621otrFkd7XUg/sAW02/v0SJNz0h+tJaWLl3uJy9yjy2FWNhLahjPcg8Zg2oujzGzg6yDFtvgQJgAR/R36wCGDJf6JWkDavl/u59wn5/1HkrHP1H2uLCzbIiv3KVZ7arDD6rdfCtjh31YcNynus1CF+QXHD6uE2QG5By6PlAjjfrFz6TOm8cxb99SvfRPPuQQbMyR0K3Z4jKS6vo5MEXNPKj1Z83QrUxT+gRphJ4QPwPHck7UdQjjYd8IQIHXVx3rpDin101vybzrkgKwVLe25cIxaSdDPSEdf5KjBWGPYzoguyvnkOdCMGezcZtKpoBOEpXwCqHWafRnb8mRJZjTSSjqpUc3N/Eka6lQhU8q5DTmv0JVUWYOepU9/7J9Jr87hoXv6AO1Z+iwUNWYvJgoVP6b9eKUneyZQkcqpwe HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:32 -0700] "GET /M?S=E8uHisxar7O9EU+Xj/bjFfG/F0DiJ/jJd3AqJDCDBJTMoRzENkuLNqgHIFa+0Ev+ICB88NJD+GaunKvj2dU4bleSWJnaDUMPTm1IszFqUcStGejs2/731x27mbIbof5MJfu1CINBxu79+tRDAjYvy4X/sh5t11gbDyZ4tUBzvgWXe5uX9/yDCod/4rX2ScADf0pv9QpAbE+IUY+wdmbsEWWjmd5KA6JaVD6p0i15k60LxgY+I+d3OLS25N45UFA6vrwRWc7K7Wv1l7UPOn7GaCeW1Bu7m5w+AXQHbivqN23dFZELQKXHyxypWt9e+E3STO6sqtKIJD2Jgg30zOINlacymc3xlHVnHk0Fl1OROnSkhrXLVxC3jDGS8quWfFg2IaWu7ttb4igc2n507Gqkrv1SCKgdnFg0O4Lxew6gTWEP//AA5oWO+SMVQK8nVG3v9mcwFH1csgJs3h/ee7V1KGy2yBakI5fYAQYoazpUzipBsCYzpIYRjJKHUUio4rqWM/B3Rxt8XfY5+m2mUlqc8mm51Ufu+VJydD7okEXIr55CgWrXPw0V7En05BTyYfc/KSey6I41+b8XSfAU76c39xYxHtVU5L36Lih/CtpWSkhOEPs7jh0amgXGyan1/4LdqiY/bPnWQHClwjhxpB2xd3PnCNvQgkSA1qLVdRKQsCbDFGKl4sVhFizUvBW3B3tE8lBflSTn3fXhvrW63EkFvBc6rn42T5fLHGeMOSnZeM6lM1msx+MOeSC/QP/rHNl3dAKtfnEPprGmvO9Fe72u8ZNfQJj/4Z/e0roAv3dULGggwRn9cZ2lZnTBt HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:34 -0700] "GET /b?o=7vnWl20PrUd+QNVGmjUfWga9pFWKff8BFkCKQo5Cr1IMX+von964Y86V+kq+gVpYalIS7GHVLa4/5C9N7vBZESseEg7nr9aRSZnNHe89cWuiQOWDwwV3bYqBnIC7dxnS04NapCtgowNVUSDiA8Kkaf1DpyNCB9WAZnDFwTwBOeVIaSuh0toG0wNiyABoPIlRLCtIFhBra+iyVYqT2CYYjphKVwCVpk47TXKdcAYRFQCgc71Vdcnqrp3mKh/M2ecL+0UogxM+hwS7mxYdojXKwxTx/mgBMfIfdexKNGErsEoNDvubxJjs2hsfZOqivMDJsWGneKxcfY4GoaC/opJ/YOoKsKAT1uSiBmkVKi2n9y/sp6aGQ9Sr9owYEK4cVXCNHLiQC5gGQ1jNIRphIBRkLgG2osVGjBO380FnOnX25YMzUD3Uf0WjVWmpd/03rc4SM8BWhAmkKJwDeIQe6UuxM51Jmws46w4J6IxCaHSQvT5O5NgNPxd91wpTuNSb5rO1MM5E9VbWSDp5GCjFV1eL4Yu1hZr/r92vUoyUKN5U3tyCzsK+zysYqiaRBMivph6XQCiaZgVW7jaGQiqF9P84bpICSl+B1mLmQuXkKhC6nJ7hDcb9j+9js8WRqNPmw+8RGeNsKTU2fLM5dBZX3pV9bdfyR/BE6h176p5jW1VoAMl1zEVAygAgIB6QGtd0D4qqqVikM8ZOIVQtqQsQDdBlja16QBFrvUTTc2Aj2P6jbABHTaT2EIUjte36ElAJ6htwBq+jJhT4fo6o4RJtsR7q4ZLy+cn9RqPaYy3TNfAvDBK8YLl99WeCmz7KeVKjD4zYEbO8Zp4YdmnyUTUerO HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:35 -0700] "GET /R?f=5hP8oyOR8/Opz/N/LEUR6Guk2RbM5El8jVDT2i/mChl1VVXFyAhzjKMKty9saPIlOIXcIkOCQE12j53726h4pLNgyiNJnk4a0apIRM1yGfWHwjkPoWB6f0tedp2AR5e7w/LQkVOU3F63r9yWUMso3rseRJ6/Rly2naq3BUAi3wPsQDqAvoxJgtTMTpg4gcyhO8kRvS647Qnk4PIvZM1JHpWZA4qj+0ORlOhAECqR9DXdrl62e70sculKKsX/9HDhxtGMj2WDojfo9KDqCF5+XHLF5Ow4CYEtbq/0GkD50z1FlZUxnVYF6A+SoDvzfkz/AmCwHE70e3jZVLG2mG+p1973E94Le+rFdk2pqAwJHKPeOqsI99eKDSYLYhZbS/rT32ZTf2JR1Gcd0zNPLCn7F0mlAJWSpRF54HYxL0gNDN0RHm7m2BtOa9tOohtnSkhqlYou1g1I/RRNAUUwLJkBTC9io4zMKlCxFxHPMjor1BmgWFqNJ8ht9q2kbr8gM3X/EBlU1R2cRJXgRN1Uh3XLlsCYC/fVHTZERyvodbmxEpMF7gFBYucAmOxZoZ/1xFIxX+GXAm+xAlhG3yWmn0ZrTnCaauAuZNYCXx7OJKI9fkWeVn/dxSDz11ORywXLK0chp+sW+bTn6xSgxlm/5PnBp0hqwbQ7KfX8pbYlqy5Q7YGEmrPeKvxkCr4kPzaQ0NGVZLWyAHf1uSNzTLCAXj+EdzyMhB/OB6QgZjZbzR3Q3dWe4YGDYQgaRcro7+GXvKHxGC5SkEa4EZE4CpB36wfjg0jMlXKaQFhSMY5Ls1kFMiGf6tRRFjvaFbqm5vGrl/bhVmtWNMQHrE HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:37 -0700] "GET /r?G=uy+ctb3hcLxv6WOFIKEbWu7dAbIOduHuP6mQfed/oChmrjN5CyTVdSwRcnCIyBFpNzerN5IMLIWR9c+8EwwPS3C2NKaHbX3300SCabhiFEMgijjxwSCLWvuMORKbX7NksAM78Ok92igCdiEdGmD6o8lCP7FKWEJwVd6y3Mchz6BExqz4QjH4OLAog1bJrOjGKCmbyM/8wMnGaMBQ/lo9PKcV7djqOhWSy8YJeY3lYJ3MQt6nuI3aGZn+LvmO/vLTSxxsgoFW+dqSK4eRJkn+zvAJcKTaEbqXgB/y1vQyB9aCtJwPSW559FAHl6V7rTu5yXlz04EmEwM4xUMecJRX2xeE++WF1m//Cz0G9PfRLLIM6nHFk4xn5OQ5aakqE+mc8gq9eQrtxewF1B4bfNY9Wey+p0cJgUdE9f7dVUq5iWLtZ76hmDkXoM6iT4HMiAOezbwgyzTCOt1aGcEhZnJtf+UMCPvgp8lOIvmm39sGVgHNTRhAE9Qg/lRsECjdRqWLL81V3LoJv+pnNKN5XVBgI7uqLAhf0ze+lbh8KH3XFqenVLUdmcXvnpobICLP5x56Xue3DEBJI1Xyt8BBB1+0ZUE1WIovsHOJENDzuG+HTLwPYXu+M9iEdjCAbs2++oihiOVRgaD51ruPY/o+XKaOJ8NJCbsQX7e+HJFuzx+MLuaNcYTya+oaSJbxagsBGG18dAFbvkWCj7N+JKH/nqZMqw1xzgE0Ykf6ii7/cU4MusA5EvfNxVD5DGzixmwgcnRatZTJwb0ccivqi2DoYi0EEzLrF4qKiI5dhHh90kWkihRVLxXIrB7Oa0t+De+ HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:39 -0700] "GET /T?j=jKuqEGUDC8ShFf7CIz8LHhzMH2ccneLxX83ZvV0cg2CZlMVo2qH4fc3F2anfnM+Pi61S+WFTI6sXiZE/2eXscvaj2Va7UsFKh8nkAg6aNJmYmiE8In4wejcVIyYO+4QFknsSO/i7ZAcUvrNZgb+xjSCPXvPBLQxQJ/TsaDczyZME09Xq9RWKr3MqkvwUng69980YaQs67gy/GwPbvJwlMhy0l6+yEfjvUwC+kwmK4tWqHHJe9s96QXpGtTbJwHcFd6WQjIbsK81iWZkDsFgs8nPZN/gxwaWGH907Nw4v2xKe+WVa8u7VVcDeNCNamFLyuVFvP4vtpQEBN12jEhq3Ou/qA/7VnyGUsbMtcCE3C2/dG5ZWPPgUUeFI/9zqi/oR198VrjF8DqTlYRV7jbp7NqmgwTY9+yIic7lhS70PzVn49M35jFcFVyVJhiXVn+lYhz418yUUKAQqt7ZlFit9MYdXfVRmg5nNmVqWfFl0eYTcCgeMtW7JEmf7s1YwTY4Hm7tL2lMrq2WPg6o8SiO44OWApfj2UIk8nENHDPGu5MA0Z7ugIfmV3dKns51AqEnCSnQk/6LTZoSffR9DDQd8K4WjxZcmhhQvY+vWs0fCDxt/pMFyFyAP3ani9/0RC3hrd4YGhGqEMGgkd5qfHgMzHNvRCSnr6d7X+/EDUCr2BofaoEBNGYJJuBIHznCmj2/HlXb8yoTZIRH6rSzg8Ra/ifzqj40nwBjI0pFSV1Nsy41F484mOnIilvmhFfG6X7oglSTJbq4qQHb3JXasgvVFcQbOhju9I0K5obWu7QAMee4SCOnIUhb4szj+74b2PG HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
213.85.255.195 - - [24/Mar/2015:00:17:41 -0700] "GET /g?x=5+1CPLS2BDhJQ1m1flsd89ogv1v86fBNg+oCjIBwJu1Cfx3okOHehwOcti8quPR49GG8pzar0mIcju9YUVsQ5XRViA+4faaffEZOecERxNab3zPkMlaUL3ToJFy6oWMAFvMxAEZsgLI7PPCbDX3QHHLRVaYlGuixJuKhh8B883bH4y4c/NTLvVtLfOWTbXBzVLv0oIRoYOmBjl08y+yHtqXfCzO6y2MKPMhSDpVZLOJeKcrOa14Ey26hLThHXHGwOCRFF9aMuG2QIZ8dBfmcsPPkV0ELm/axrlEu/eyQSgBLeE3Ndv0k+PFRc4EgnLbLpl074xr7vZnthDS1n/C8AGtEp1GXPxuMvaAQNqU/FkcILZZtTQJMVY9gQn08ORMrcLiixLDAN4Swh4dmX0p2nAMEkAqI4oO0vkdI6C9DAWaJjDpAYapXvdM7PEuu04s+NWgPrQCVGERHo4XxFwwf6tWvnW9I4QoiwBP47u7kvlWxDHH4WKdAjNT7wS4dcr9oubEhhhFk4uRHtGWn21l7biJtdxtzkSn+XP8BJRq19VJ1Paj6SL1T HTTP/1.1" 404 73 "-" "Mozilla/4.0 (compatible; MSIE 8.0; Win32)"
31.184.238.152 - - [24/Mar/2015:00:19:45 -0700] "GET /logs/access.log HTTP/1.1" 200 164175 "http://buy-cytoxan.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36 OPR/20.0.1387.64"
162.244.11.73 - - [24/Mar/2015:00:20:32 -0700] "GET /logs/access.log HTTP/1.1" 200 34504 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:00:20:33 -0700] "GET /logs/access.log HTTP/1.1" 200 164684 "http://ordermobiconlinequickshipping.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
188.165.15.10 - - [24/Mar/2015:00:25:55 -0700] "GET /paper2003/0306JHCol.htm HTTP/1.1" 404 88 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
100.43.91.12 - - [24/Mar/2015:00:26:26 -0700] "GET /Socialist/05MayElection.htm HTTP/1.1" 200 3612 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
31.184.238.152 - - [24/Mar/2015:00:30:44 -0700] "GET /logs/access.log HTTP/1.1" 200 165314 "http://www.theknot.com/wedding/aciclovir-online" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
180.76.6.158 - - [24/Mar/2015:00:31:01 -0700] "GET /Struggle-Archive.htm HTTP/1.1" 200 2287 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
31.184.238.152 - - [24/Mar/2015:00:31:31 -0700] "GET /logs/access.log HTTP/1.1" 200 165772 "http://buy-venlafaxine-75mg.over-blog.com" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
103.14.252.249 - - [24/Mar/2015:00:34:26 -0700] "GET /logs/access.log HTTP/1.1" 200 34931 "https://www.google.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"
103.246.38.196 - - [24/Mar/2015:00:34:26 -0700] "GET /logs/access.log HTTP/1.1" 200 166025 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; MS-RTC LM 8; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
141.101.31.80 - - [24/Mar/2015:00:38:59 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.1634 Safari/535.19 YE"
141.101.31.80 - - [24/Mar/2015:00:38:59 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.289 Version/12.01"
141.101.31.80 - - [24/Mar/2015:00:39:00 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.289 Version/12.01"
141.101.31.80 - - [24/Mar/2015:00:39:00 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Nichrome/self/19"
141.101.31.80 - - [24/Mar/2015:00:39:00 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Nichrome/self/19"
141.101.31.80 - - [24/Mar/2015:00:39:01 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11"
141.101.31.80 - - [24/Mar/2015:00:39:01 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.91 Safari/537.11"
37.228.107.40 - - [24/Mar/2015:00:39:09 -0700] "GET /pdf/che_sos.pdf HTTP/1.1" 200 207560 "http://www.google.co.in/m?q=free+cheguvera+book+pdf&client=ms-opera-mini&channel=new" "Opera/9.80 (Android; Opera Mini/7.6.35843/36.1370; U; en) Presto/2.12.423 Version/12.16"
31.184.238.152 - - [24/Mar/2015:00:41:50 -0700] "GET /logs/access.log HTTP/1.1" 200 168441 "http://buyfamotidine20mgquickshipping.snack.ws" "Mozilla/5.0 (Windows NT 5.1; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [24/Mar/2015:00:42:31 -0700] "GET /logs/access.log HTTP/1.1" 200 168662 "http://doxycycline-100-mg-buy.page.tl" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
27.153.233.108 - - [24/Mar/2015:00:43:30 -0700] "GET /logs/access.log HTTP/1.1" 200 35906 "http://redlug.com/" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
27.153.233.108 - - [24/Mar/2015:00:43:31 -0700] "GET /socview/SV0302TroublesReview.htm HTTP/1.1" 200 2434 "http://redlug.com/" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36"
46.147.146.177 - - [24/Mar/2015:00:44:36 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4356.apishops.ru/" "Opera/9.00 (Windows NT 5.1; U; en)"
46.147.146.177 - - [24/Mar/2015:00:44:37 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4356.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; FunWebProducts)"
46.147.146.177 - - [24/Mar/2015:00:44:38 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4356.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0; .NET CLR 1.0.2914)"
46.147.146.177 - - [24/Mar/2015:00:44:39 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4356.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 5.5; Windows NT 5.0) Opera 7.02 Bork-edition [en]"
103.14.252.249 - - [24/Mar/2015:00:46:10 -0700] "GET /logs/access.log HTTP/1.1" 200 35642 "https://www.google.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"
202.46.55.206 - - [24/Mar/2015:00:47:50 -0700] "GET /socview/04SpringContents.htm HTTP/1.1" 404 89 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:00:52:23 -0700] "GET /logs/access.log HTTP/1.1" 200 170607 "http://ilosone-order-online.soup.io" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:00:53:08 -0700] "GET /logs/access.log HTTP/1.1" 200 170854 "http://tizanidine-buy-no-prescription.snack.ws" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:01:03:11 -0700] "GET /logs/access.log HTTP/1.1" 200 171112 "http://gravatar.com/frapatmerdigati" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
31.184.238.152 - - [24/Mar/2015:01:03:56 -0700] "GET /logs/access.log HTTP/1.1" 200 171376 "http://ordersildalis100mgonlinewithoutprescription.soup.io" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
141.101.31.80 - - [24/Mar/2015:01:07:08 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0"
141.101.31.80 - - [24/Mar/2015:01:07:09 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.1634 Safari/535.19 YE"
141.101.31.80 - - [24/Mar/2015:01:07:09 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.1634 Safari/535.19 YE"
141.101.31.80 - - [24/Mar/2015:01:07:09 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"
141.101.31.80 - - [24/Mar/2015:01:07:10 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"
141.101.31.80 - - [24/Mar/2015:01:07:10 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blondebitch.soup.io/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.61"
141.101.31.80 - - [24/Mar/2015:01:07:11 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blondebitch.soup.io/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.10.229 Version/11.61"
66.249.79.35 - - [24/Mar/2015:01:11:55 -0700] "GET /images/150203/YaWBelfast1.jpg HTTP/1.1" 200 19541 "-" "Googlebot-Image/1.0"
78.58.143.166 - - [24/Mar/2015:01:11:59 -0700] "GET /logs/access.log/RK=0/RS=3pBGsDoyNk_9CI1_kCqOS2vIjHE- HTTP/1.1" 404 88 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
78.58.143.166 - - [24/Mar/2015:01:11:59 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:01:13:52 -0700] "GET /logs/access.log HTTP/1.1" 200 173881 "http://diclofenac-buy-online.snack.ws" "Mozilla/5.0 (Windows NT 6.1; rv:27.0) Gecko/20100101 Firefox/27.0"
31.184.238.152 - - [24/Mar/2015:01:14:36 -0700] "GET /logs/access.log HTTP/1.1" 200 174093 "http://aripiprazole-20mg-buy-cheap.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.12785 YaBrowser/13.12.1599.12785 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:01:24:38 -0700] "GET /logs/access.log HTTP/1.1" 200 174376 "http://buydesogenonline.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:01:25:21 -0700] "GET /logs/access.log HTTP/1.1" 200 174619 "http://order-azithromycin-250mg.soup.io" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
89.140.152.184 - - [24/Mar/2015:01:29:17 -0700] "GET / HTTP/1.1" 200 1273 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1"
31.184.238.152 - - [24/Mar/2015:01:35:11 -0700] "GET /logs/access.log HTTP/1.1" 200 175036 "http://buy-famvir-500mg-cheap.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
141.101.31.80 - - [24/Mar/2015:01:35:28 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; rv:15.0) Gecko/20100101 Firefox/15.0.1"
141.101.31.80 - - [24/Mar/2015:01:35:29 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; Edition Yx) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [24/Mar/2015:01:35:29 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; Edition Yx) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [24/Mar/2015:01:35:30 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.2; WOW64; MRA 8.0 (build 5784)) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [24/Mar/2015:01:35:30 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.2; WOW64; MRA 8.0 (build 5784)) Presto/2.12.388 Version/12.11"
141.101.31.80 - - [24/Mar/2015:01:35:30 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0"
141.101.31.80 - - [24/Mar/2015:01:35:31 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0"
31.184.238.152 - - [24/Mar/2015:01:44:53 -0700] "GET /logs/access.log HTTP/1.1" 200 176813 "http://cabergoline-05mg-buy-without-rx.soup.io" "Opera/9.80 (Windows NT 6.1; Win64; x64) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [24/Mar/2015:01:45:30 -0700] "GET /logs/access.log HTTP/1.1" 200 177038 "http://order-motilium.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36 OPR/19.0.1326.63"
180.76.6.51 - - [24/Mar/2015:01:45:41 -0700] "GET /paperarticles/?C=N;O=A HTTP/1.1" 200 1735 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
100.43.81.131 - - [24/Mar/2015:01:46:01 -0700] "GET /logs/access_140823.log HTTP/1.1" 200 1535429 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)"
148.251.75.46 - - [24/Mar/2015:01:49:47 -0700] "GET /LabHist/ContentsList.htm HTTP/1.1" 200 30482 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.93 Safari/537.36"
66.249.79.27 - - [24/Mar/2015:01:53:27 -0700] "GET /YaW/DayXPoster2_files/image001.gif HTTP/1.1" 404 88 "-" "Googlebot-Image/1.0"
31.184.238.152 - - [24/Mar/2015:01:54:31 -0700] "GET /logs/access.log HTTP/1.1" 200 178065 "http://repaglinide1mgbg.forumcircle.com" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:02:40 -0700] "GET /logs/access.log HTTP/1.1" 200 178316 "http://cabergoline-025mg-order-no-prescription.soup.io" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:03:21 -0700] "GET /logs/access.log HTTP/1.1" 200 178582 "http://gravatar.com/sorcontrorostjackja" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
141.101.31.80 - - [24/Mar/2015:02:03:23 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 5.1; Edition Ukraine Local) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [24/Mar/2015:02:03:23 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0"
141.101.31.80 - - [24/Mar/2015:02:03:24 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1; rv:8.0) Gecko/20100101 Firefox/8.0"
141.101.31.80 - - [24/Mar/2015:02:03:24 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.7.39 Version/11.00"
141.101.31.80 - - [24/Mar/2015:02:03:24 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.7.39 Version/11.00"
141.101.31.80 - - [24/Mar/2015:02:03:25 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.12 (KHTML, like Gecko) Maxthon/3.0 Chrome/18.0.966.0 Safari/535.12"
141.101.31.80 - - [24/Mar/2015:02:03:26 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.12 (KHTML, like Gecko) Maxthon/3.0 Chrome/18.0.966.0 Safari/535.12"
157.55.39.217 - - [24/Mar/2015:02:09:18 -0700] "GET /logs/access_140512.log HTTP/1.1" 404 88 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
142.54.184.181 - - [24/Mar/2015:02:10:43 -0700] "GET / HTTP/1.1" 200 1273 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
142.54.184.181 - - [24/Mar/2015:02:10:45 -0700] "GET / HTTP/1.1" 200 1273 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.0.3705)"
31.184.238.152 - - [24/Mar/2015:02:11:36 -0700] "GET /logs/access.log HTTP/1.1" 200 180883 "http://strattera-10mg-buy-cheap.soup.io" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.13014 YaBrowser/13.12.1599.13014 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:12:15 -0700] "GET /logs/access.log HTTP/1.1" 200 181170 "http://gravatar.com/topkbulboburomes" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.44.93.25 - - [24/Mar/2015:02:16:44 -0700] "GET /logs/access.log HTTP/1.1" 200 37566 "https://www.google.ru/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36"
157.55.39.237 - - [24/Mar/2015:02:18:56 -0700] "GET /paper2003/0306France.htm HTTP/1.1" 200 3979 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
31.184.238.152 - - [24/Mar/2015:02:20:46 -0700] "GET /logs/access.log HTTP/1.1" 200 181849 "http://lansoprazole-15mg-buy-online.snack.ws" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:21:22 -0700] "GET /logs/access.log HTTP/1.1" 200 182104 "http://order-acetazolamide-no-rx.snack.ws" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [24/Mar/2015:02:29:32 -0700] "GET /logs/access.log HTTP/1.1" 200 182319 "http://eksustiva600mg.forumcircle.com" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.12785 YaBrowser/13.12.1599.12785 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:30:09 -0700] "GET /logs/access.log HTTP/1.1" 200 182597 "http://orderbudesonideonlineie.over-blog.com" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36"
101.251.211.237 - - [24/Mar/2015:02:30:21 -0700] "GET /logs/access.log HTTP/1.1" 200 37761 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
141.101.31.80 - - [24/Mar/2015:02:31:16 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Opera/9.80 (Windows NT 6.1; MRA 6.0 (build 5976)) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [24/Mar/2015:02:31:31 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0"
141.101.31.80 - - [24/Mar/2015:02:31:32 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 6.2; rv:16.0) Gecko/20100101 Firefox/16.0"
141.101.31.80 - - [24/Mar/2015:02:31:32 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"
141.101.31.80 - - [24/Mar/2015:02:31:33 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"
141.101.31.80 - - [24/Mar/2015:02:31:33 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1; rv:7.0) Gecko/20100101 Firefox/7.0"
141.101.31.80 - - [24/Mar/2015:02:31:34 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://blonde.aircus.com/" "Mozilla/5.0 (Windows NT 5.1; rv:7.0) Gecko/20100101 Firefox/7.0"
66.249.79.43 - - [24/Mar/2015:02:32:16 -0700] "GET /images/logos/backup.gif HTTP/1.1" 200 51 "-" "Googlebot-Image/1.0"
31.184.238.152 - - [24/Mar/2015:02:38:27 -0700] "GET /logs/access.log HTTP/1.1" 200 184710 "http://lamprene-50mg-buy-no-prescription.soup.io" "Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.16"
31.184.238.152 - - [24/Mar/2015:02:39:07 -0700] "GET /logs/access.log HTTP/1.1" 200 184925 "http://yasmin-order.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.12785 YaBrowser/13.12.1599.12785 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:48:00 -0700] "GET /logs/access.log HTTP/1.1" 200 185193 "http://gravatar.com/freeftherfmemnakompai" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:48:39 -0700] "GET /logs/access.log HTTP/1.1" 200 185446 "http://www.theknot.com/wedding/trandate-and-no" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
219.142.192.196 - - [24/Mar/2015:02:55:11 -0700] "GET /logs/access.log HTTP/1.1" 200 38039 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
176.25.159.80 - - [24/Mar/2015:02:56:15 -0700] "GET /logs/access_140427.log HTTP/1.1" 404 88 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:02:57:08 -0700] "GET /logs/access.log HTTP/1.1" 200 186209 "http://buygriseofulvin.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 OPR/18.0.1284.68"
31.184.238.152 - - [24/Mar/2015:02:57:50 -0700] "GET /logs/access.log HTTP/1.1" 200 186475 "http://ordercetirizineonline.snack.ws" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0"
141.101.31.80 - - [24/Mar/2015:02:58:55 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 5.1; Edition Yx) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [24/Mar/2015:02:58:57 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [24/Mar/2015:02:58:57 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [24/Mar/2015:02:58:58 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [24/Mar/2015:02:58:58 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4"
141.101.31.80 - - [24/Mar/2015:02:58:58 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; U; Edition Yx; ru) Presto/2.10.289 Version/12.02"
141.101.31.80 - - [24/Mar/2015:02:58:59 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; U; Edition Yx; ru) Presto/2.10.289 Version/12.02"
203.106.214.137 - - [24/Mar/2015:03:01:10 -0700] "GET /logs/access.log HTTP/1.1" 200 38244 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
46.147.146.177 - - [24/Mar/2015:03:01:40 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4689.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0; .NET CLR 1.1.4322)"
46.147.146.177 - - [24/Mar/2015:03:01:40 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4689.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0; .NET CLR 1.1.4322)"
46.147.146.177 - - [24/Mar/2015:03:01:41 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4689.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
46.147.146.177 - - [24/Mar/2015:03:01:42 -0700] "GET / HTTP/1.1" 200 9589 "http://msk4689.apishops.ru/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows ME) Opera 7.11 [en]"
188.165.15.10 - - [24/Mar/2015:03:04:02 -0700] "GET /LabHist/LabHist/17yearold.htm HTTP/1.1" 404 88 "-" "Mozilla/5.0 (compatible; AhrefsBot/5.0; +http://ahrefs.com/robot/)"
31.184.238.152 - - [24/Mar/2015:03:06:28 -0700] "GET /logs/access.log HTTP/1.1" 200 189524 "http://buy-sucralfate-1000mg-online.soup.io" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36"
157.55.39.237 - - [24/Mar/2015:03:07:02 -0700] "GET /Election/031108TB.htm HTTP/1.1" 200 1042 "-" "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
31.184.238.152 - - [24/Mar/2015:03:07:05 -0700] "GET /logs/access.log HTTP/1.1" 200 189964 "http://ordernaproxen250mg.forumcircle.com" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"
117.169.1.19 - - [24/Mar/2015:03:09:53 -0700] "GET /logs/access.log HTTP/1.1" 200 38454 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
85.214.230.139 - - [24/Mar/2015:03:10:10 -0700] "GET /logs/access.log HTTP/1.1" 200 38286 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:03:16:03 -0700] "GET /logs/access.log HTTP/1.1" 200 190709 "http://ordercetirizinecheap.snack.ws" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
103.246.38.196 - - [24/Mar/2015:03:16:09 -0700] "GET /logs/access.log HTTP/1.1" 200 190957 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; MS-RTC LM 8; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
170.252.160.1 - - [24/Mar/2015:03:16:10 -0700] "GET /logs/access.log HTTP/1.1" 200 38358 "https://www.google.co.in/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:03:16:41 -0700] "GET /logs/access.log HTTP/1.1" 200 191468 "http://glucotrol-order.soup.io" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
74.67.210.175 - - [24/Mar/2015:03:17:06 -0700] "GET /logs/access.log HTTP/1.1" 200 38600 "https://www.google.co.uk/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:03:24:48 -0700] "GET /logs/access.log HTTP/1.1" 200 191952 "http://gravatar.com/chemburelanlinktea" "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
31.7.232.102 - - [24/Mar/2015:03:24:53 -0700] "GET /logs/access.log HTTP/1.1" 200 38479 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:03:25:27 -0700] "GET /logs/access.log HTTP/1.1" 200 192446 "http://orderlinezolid600mgonline.snack.ws" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"
141.101.31.80 - - [24/Mar/2015:03:26:38 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; U; ru) Presto/2.10.289 Version/12.01"
141.101.31.80 - - [24/Mar/2015:03:26:38 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; Edition Yx) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [24/Mar/2015:03:26:38 -0700] "GET /access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Opera/9.80 (Windows NT 6.1; WOW64; Edition Yx) Presto/2.12.388 Version/12.10"
141.101.31.80 - - [24/Mar/2015:03:26:39 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.0; rv:17.0) Gecko/20100101 Firefox/17.0"
141.101.31.80 - - [24/Mar/2015:03:26:39 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.0; rv:17.0) Gecko/20100101 Firefox/17.0"
141.101.31.80 - - [24/Mar/2015:03:26:39 -0700] "GET /logs/access_130930.log HTTP/1.1" 404 73 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
141.101.31.80 - - [24/Mar/2015:03:26:40 -0700] "GET /access_130930.log HTTP/1.1" 404 89 "http://pristiq.forumcircle.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"
37.59.131.238 - - [24/Mar/2015:03:26:49 -0700] "GET /LabHist/ContentsList.htm HTTP/1.1" 200 12093 "http://redlug.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"
31.184.238.152 - - [24/Mar/2015:03:33:28 -0700] "GET /logs/access.log HTTP/1.1" 200 194447 "http://order-ethionamide-250mg-without-rx.snack.ws" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.15"
31.184.238.152 - - [24/Mar/2015:03:34:05 -0700] "GET /logs/access.log HTTP/1.1" 200 194671 "http://gravatar.com/agridelnapande" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
84.203.78.80 - - [24/Mar/2015:03:37:17 -0700] "GET /socview/0306SCW.htm HTTP/1.1" 200 5294 "http://www.google.ie/url?sa=t&source=web&cd=10&ved=0CDsQFjAJ&url=http%3A%2F%2Fredlug.com%2Fsocview%2F0306SCW.htm&rct=j&q=the%20blue%20shirts%20in%20spain&ei=vD0RVbjQNM3e7AbqpoDoCw&usg=AFQjCNGa47mJ-C5rv-LJa84XqMF0199ErA" "Mozilla/5.0 (Linux; U; Android 4.4.2; en-gb; HTC_Desire_610 Build/KOT49H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
84.203.78.80 - - [24/Mar/2015:03:37:17 -0700] "GET /cwi.css HTTP/1.1" 404 73 "http://redlug.com/socview/0306SCW.htm" "Mozilla/5.0 (Linux; U; Android 4.4.2; en-gb; HTC_Desire_610 Build/KOT49H) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
217.12.206.140 - - [24/Mar/2015:03:38:29 -0700] "GET / HTTP/1.1" 200 1273 "http://redlug.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"
@@ -0,0 +1,8 @@
aaaaaaaabbbbbbbbaaaaaaaabbbbbbbb
aaaaaaaaabbbbbbbbbaaaaaaaaabbbbbbbbb
aaaaaaaaaabbbbbbbbbbaaaaaaaaaabbbbbbbbbb
aaaaaaaaaaabbbbbbbbbbbaaaaaaaaaaabbbbbbbbbbb
aaaaaaaaaaaabbbbbbbbbbbbaaaaaaaaaaaabbbbbbbbbbbb
aaaaaaaaaaaaabbbbbbbbbbbbbaaaaaaaaaaaaabbbbbbbbbbbbb
aaaaaaaaaaaaaabbbbbbbbbbbbbbaaaaaaaaaaaaaabbbbbbbbbbbbbb
aaaaaaaaaaaaaaabbbbbbbbbbbbbbbaaaaaaaaaaaaaaabbbbbbbbbbbbbbb
@@ -0,0 +1,5 @@
aaaabbbbaaaabbbbaaaabbbbaaaabbbb
aaaaabbbbbaaaaabbbbbaaaaabbbbbaaaaabbbbb
aaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbb
aaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbb
aaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbb
@@ -0,0 +1,7 @@
aabbaabbaabbaabbaabbaabbaabbaabb
aaabbbaaabbbaaabbbaaabbbaaabbbaaabbbaaabbbaaabbb
aaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbbaaaabbbb
aaaaabbbbbaaaaabbbbbaaaaabbbbbaaaaabbbbbaaaaabbbbbaaaaabbbbbaaaaabbbbbaaaaabbbbb
aaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbbaaaaaabbbbbb
aaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbbaaaaaaabbbbbbb
aaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbbaaaaaaaabbbbbbbb
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,94 @@
jsmith@apache.org
someone@[216.109.118.76]
someone@yahoo.com
jsmith@apache.org
jsmith@apache.com
jsmith@apache.net
jsmith@apache.info
jsmith@apache.
jsmith@apache.c
someone@yahoo.museum
someone@yahoo.mu-seum
andy.noble@data-workshop.com
andy-noble@data-workshop.-com
andy-noble@data-workshop.c-om
andy-noble@data-workshop.co-m
andy.noble@data-workshop.com.
andy.noble@\u008fdata-workshop.com
andy.o'reilly@data-workshop.com
andy@o'reilly.data-workshop.com
foo+bar@i.am.not.in.us.example.com
foo+bar@example+3.com
test@%*.com
test@^&#.com
me@at&t.net
me@att.net
someone@-test.com
someone@test-.com
joe1234567890blow@apa,che.org
joe1234567890blow@apache.o,rg
joe1234567890blow@apache,org
joe1234567890blow @apache.org
joe1234567890blow@ apache.org
joe1234567890blow@apache.org
joe1234567890blow@apache.org
joe1234567890 blow@apache.org
joe1234567890blow@apa che.org
joe12345678901blow@apache.org
joe1234567890$blow@apache.org
joe1234567890-@apache.org
joe1234567890_@apache.org
joe1234567890+@apache.org
joe1234567890!@apache.org
joe1234567890*@apache.org
joe1234567890'@apache.org
joe1234567890%45@apache.org
joe1234567890?@apache.org
joe1234567890&@apache.org
joe1234567890=@apache.org
+joe1234567890@apache.org
!joe1234567890@apache.org
*joe1234567890@apache.org
'joe1234567890@apache.org
%joe123456789045@apache.org
?joe1234567890@apache.org
&joe1234567890@apache.org
=joe1234567890@apache.org
+@apache.org
!@apache.org
*@apache.org
'@apache.org
%@apache.org
?@apache.org
&@apache.org
=@apache.org
joe1234567890.@apache.org
.joe1234567890@apache.org
.@apache.org
joe1234567890.ok@apache.org
joe1234567890..ok@apache.org
..@apache.org
joe1234567890(@apache.org
joe1234567890)@apache.org
joe1234567890,@apache.org
joe1234567890;@apache.org
\"joe1234567890.\"@apache.org
\".joe1234567890\"@apache.org
\"joe1234567890+\"@apache.org
\"joe1234567890!\"@apache.org
\"joe1234567890*\"@apache.org
\"joe1234567890'\"@apache.org
\"joe1234567890(\"@apache.org
\"joe1234567890)\"@apache.org
\"joe1234567890,\"@apache.org
\"joe1234567890%45\"@apache.org
\"joe1234567890;\"@apache.org
\"joe1234567890?\"@apache.org
\"joe1234567890&\"@apache.org
\"joe1234567890=\"@apache.org
\"..\"@apache.org
abc-@abc.com
abc_@abc.com
abc-def@abc.com
abc_def@abc.com
abc@abc_def.com
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
import os
# 100 megabytes
LIMIT = 1024 * 1024 * 100
# read the small sample
with open('small', 'rb') as f:
small = f.read()
smallsize = len(small)
# copy-paste it enough times to the big file
total = 0
with open('big', 'wb') as f:
while total < LIMIT:
f.write(small)
total += smallsize
+101
View File
@@ -0,0 +1,101 @@
HEAD file://cwidoaajjb.pqzeztqtg.iagnuhmdq.npliaihmqn.yuptnwn/hlhkojvjvzmsgccwcpwhh/qfliekillmmdz/aypkwffmdojvpdodmrouzxuupqp/gjqnmbk/mnbtpocjbe/ttvqsflbsqirgahmutddqucg/nkycantossaikwulmgemuqttwx/foqeceoyiowyeftxpr/syjcvolygaguylfkx/gwgx?7B9Jq5CNzjzSFzJl7cCL4oUX HTTP/6.2
Content-Disposition: attachment; filename="fname.ext"
Content-Language: da
If-Match: "737060cd8c284d8af7ad3082f209582d"
If-None-Match: "737060cd8c284d8af7ad3082f209582d"
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Connection: Upgrade
X-Powered-By: PHP/5.4.0
Proxy-Authenticate: Basic
Warning: 199 Miscellaneous warning
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket
X-Att-Deviceid: GT-P7320/P7320XXLPG
Alt-Svc: http/1.1="http2.example.com:8001"; ma=7200
Accept-Ranges: bytes
Content-Language: da
Cache-Control: no-cache
Age: 12
Accept-Encoding: gzip, deflate
Content-Length: 51
WWW-Authenticate: Basic
Vary: *
Upgrade-Insecure-Requests: 1
Strict-Transport-Security: max-age=16070400; includeSubDomains
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Pragma: no-cache
Content-Length: 51
Host: en.wikipedia.org
X-Frame-Options: deny
POST https://hubgkuzz.qqwqvsfccy.psvyjbuva.afjqkipasn.zrdeeznzgo:7150/yfztaoqwaqlyuxfdkosgkegikcn/xme HTTP/6.6
Cache-Control: max-age=3600
Content-Length: 51
Content-Type: application/x-www-form-urlencoded
Upgrade: HTTPS/1.3, IRC/6.9, RTA/x11, websocket
Alt-Svc: http/1.1="http2.example.com:8001"; ma=7200
Date: Tue, 15 Nov 1994 08:12:31 GMT
Accept-Charset: utf-8
Cookie: $Version=1; Skin=new;
X-Request-ID: f058ebd6-02f7-4d3f-942e-904344e8cde5
CONNECT zwusyxlehg.qxqjpqqjzq.rnrnmjbspj.ugbkvsriyw.gpchzrlqkk:8638 HTTP/7.4
Pragma: no-cache
Transfer-Encoding: chunked
Content-Location: /index.htm
X-Att-Deviceid: GT-P7320/P7320XXLPG
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Accept-Patch: text/example;charset=utf-8
Host: en.wikipedia.org:8080
X-Forwarded-For: client1, proxy1, proxy2
Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
DNT: 1 (Do Not Track Enabled)
X-UA-Compatible: Chrome=1
Tk: ?
Refresh: 5; url=http://www.w3.org/pub/WWW/People.html
X-UA-Compatible: IE=edge
Expect: 100-continue
DNT: 0 (Do Not Track Disabled)
WWW-Authenticate: Basic
Content-Type: application/x-www-form-urlencoded
Public-Key-Pins: max-age=2592000; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g=";
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
X-Content-Type-Options: nosniff
X-Csrf-Token: i8XNjC4b8KVok4uw5RftR38Wgp2BFwql
X-Forwarded-Host: en.wikipedia.org
X-Att-Deviceid: GT-P7320/P7320XXLPG
Content-Location: /index.htm
Accept-Datetime: Thu, 31 May 2007 20:35:00 GMT
HTTP/9.5 559 u
Date: Tue, 15 Nov 1994 08:12:31 GMT
Content-Length: 348
X-Forwarded-Proto: https
Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Expires: Thu, 01 Dec 1994 16:00:00 GMT
WWW-Authenticate: Basic
Allow: GET, HEAD
Warning: 199 Miscellaneous warning
POST wllvzjwvpp.mhagladifk.joaq.rnprjmcpum.opadaxtssr HTTP/6.4
Warning: 199 Miscellaneous warning
Proxy-Authenticate: Basic
Content-Encoding: gzip
X-Forwarded-Host: en.wikipedia.org
Strict-Transport-Security: max-age=16070400; includeSubDomains
Content-Language: da
Allow: GET, HEAD
Retry-After: Fri, 07 Nov 2014 23:59:59 GMT
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
X-Forwarded-For: client1, proxy1, proxy2
HTTP/0.6 463 2bs
From: user@example.com
X-Forwarded-Host: en.wikipedia.org
X-Forwarded-Host: en.wikipedia.org
X-UA-Compatible: IE=edge
X-UA-Compatible: IE=edge
Date: Tue, 15 Nov 1994 08:12:31 GMT
@@ -0,0 +1,9 @@
127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
8.8.8.8
255.0.0.0
10.0.0.0
169.254.0.0
172.16.0.0
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
https://re2c.org
https://www.colm.net/open-source/ragel
https://github.com/diku-kmc/kleenexlang
https://github.com/skvadrik/re2c
https://arxiv.org/abs/1907.08837
https://laurikari.net/ville/spire2000-tnfa.pdf
https://www.semanticscholar.org/paper/Tagged-Deterministic-Finite-Automata-with-Lookahead-Trofimovich/3ca8101183d87580bc97dd7c1236d77bbd90a40d
http://re2c.org/2019_borsotti_trofimovich_efficient_posix_submatch_extraction_on_nfa.pdf
https://www.researchgate.net/publication/344781678_Efficient_POSIX_submatch_extraction_on_nondeterministic_finite_automata
https://kernel.org
https://en.wikipedia.org/
https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
http://190.102.237.163/jfymqrdxatqxxosr/eodoflhmefpbqunvzkwkxfgxj/ife/bbijkiueazcfwodgsddft/xpegxlfbdzafenjaqgjbnqrsb/poizlwooajtnejxpycftrcsfjkruln?DEVzXYliuaVThP2db4oE32q#fXoCDA1BJyjOUBJwpMOOC36Q7o6n
https://prlmszykmotajvhfingpy:5gJpVNFdVUCBumKIV0ciYat@tyekbzfzyn.kirctezfig.gvefopbqlf.onykhnytqd.uofiltbvdv/jiqe/odskecdswmouqaunyfuerpefcusuxa/fkqdmaueh/vzkskyxrpqkfzzjgujqmkt/qfnzplmxvunhvjq/kskwzjeueepwokxguatetegnjzgu/pysxiyoyssbfiibuonhk/wmzxsguoqoeutnkaanqqd/pkpbwvoepeutjbedkdimko/vogpbm#fBzuGdIV22C
file://ngngiosyeynlnyegckpwp:QoW1iBFx@171.234.221.207/ltdgogjynxrrnjygsltmcfihfsqfvk/mixerqujwbektqyzimadzdx/urb/vrvjsofccprkaavyyp/sycatuazj/vlmmmvozycmvpicrpcipfxywp/zddjtiahb
https://jqhvw:ssV@[4::a8:5ab]:7064/tto/xjdjuxhkqhuvmdbwn/kejaxevbfon/nxrvxlozfd/nefd/drhf/ya/meebpkpao/go/sv?XZtzUKrb4Qq19CsMmL
ftp://226.47.189.219/uttpjalgzirumdxcqstmop/rsavfunauwrnzbrbccv/qvnzgkypemnulagkcnxgmhg/vdzboggzuttu/wimrcceehdaznqnvguhi/hcmbkir/vxcincavxbheiuuqoukjsnd/rnkr/repqv/cdncqpiqhrughnlhbu?04HBSdquIv5jRN5POmtHr#t8TxSWH16brGRC79JCiBCp8bEyF
http:/laxn/rugglbrcb/znzlrhyoxapkznmedipktxhqzeohlw/rfmg/uyntiipnzdwjlfy/fktcgxrgcsfkr/rbbcxzybieozevucqxpmeq/apqyszyxgpq/zbknrolqhmtwjshockr/kicrlzsbtx?VbJp1VLkYC#mYPZplrVnb7UHSatrpGAwi
ftp://hukiuvtpzvmwmnxgomsujflyk:b1MSVh7pUWPjK24nnJoOOwKIET36s@6.119.196.62:5869/cyhsyhjykv#NlE8g3hz1Ebta8kk7LUvTm
+11
View File
@@ -0,0 +1,11 @@
set -e
rm -rf kleenexlang
git clone --recursive https://github.com/diku-kmc/kleenexlang.git
cd kleenexlang
cabal v1-sandbox init && cabal v1-sandbox add-source regexps-syntax
cabal v1-install --dependencies-only
cabal v1-configure && cabal v1-build
cd ..
rm -f kexc
ln -s kleenexlang/dist/build/kexc/kexc kexc
+16
View File
@@ -0,0 +1,16 @@
set -e
if [ -e ragel6 ] ; then
echo "ragel6 is already installed, quitting"
exit 0
fi
RAGEL_DIR=ragel-6.10
wget http://www.colm.net/files/ragel/"$RAGEL_DIR".tar.gz -O - | tar zx \
&& cd "$RAGEL_DIR" \
&& ./configure --prefix=$(pwd)/install \
&& make -j$(nproc) \
&& cd ..
ln -s "$RAGEL_DIR"/ragel/ragel ragel6
+28
View File
@@ -0,0 +1,28 @@
set -e
if [ -e ragel7 ] ; then
echo "ragel7 is already installed, quitting"
exit 0
fi
COLM_DIR=colm-0.14.7
RAGEL_DIR=ragel-7.0.4
wget http://www.colm.net/files/colm/"$COLM_DIR".tar.gz -O - | tar zx \
&& cd "$COLM_DIR" \
&& ./configure --prefix=$(pwd)/install \
&& make -j$(nproc) \
&& make install \
&& cd ..
wget http://www.colm.net/files/ragel/"$RAGEL_DIR".tar.gz -O - | tar zx \
&& cd "$RAGEL_DIR" \
&& ./configure \
--prefix=$(pwd)/install \
--with-colm="$(pwd)/../$COLM_DIR/install" \
--disable-manual \
&& make -j$(nproc) \
&& make install \
&& cd ..
ln -s "$RAGEL_DIR"/install/bin/ragel ragel7
@@ -0,0 +1,11 @@
ragel/21__cat2_4
ragel/22__cat2_8
ragel/24__cat4_2
ragel/25__cat4_4
ragel/28__cat8_2
ragel/33__rep_alt_5_3_2
ragel/34__rep_alt_13_11_7
ragel/35__rep_alt_23_19_17
ragel/36__rep_5_rep_3_rep_2
ragel/37__rep_13_rep_11_rep_7
ragel/38__rep_23_rep_19_rep_17
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,808 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
// \xaagent: "
const buffer_unit_t const_1_0[9] = {0xa,0x61,0x67,0x65,0x6e,0x74,0x3a,0x20,0x22};
// \xaauthuser:
const buffer_unit_t const_1_1[11] = {0xa,0x61,0x75,0x74,0x68,0x75,0x73,0x65,0x72,0x3a,0x20};
// \xadate:
const buffer_unit_t const_1_2[7] = {0xa,0x64,0x61,0x74,0x65,0x3a,0x20};
// \xarequest:
const buffer_unit_t const_1_3[10] = {0xa,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x3a,0x20};
// \xasize:
const buffer_unit_t const_1_4[7] = {0xa,0x73,0x69,0x7a,0x65,0x3a,0x20};
// \xastatus:
const buffer_unit_t const_1_5[9] = {0xa,0x73,0x74,0x61,0x74,0x75,0x73,0x3a,0x20};
// \xaurl: "
const buffer_unit_t const_1_6[7] = {0xa,0x75,0x72,0x6c,0x3a,0x20,0x22};
// \xauserid:
const buffer_unit_t const_1_7[9] = {0xa,0x75,0x73,0x65,0x72,0x69,0x64,0x3a,0x20};
// "\xa\xa
const buffer_unit_t const_1_8[3] = {0x22,0xa,0xa};
// host:
const buffer_unit_t const_1_9[6] = {0x68,0x6f,0x73,0x74,0x3a,0x20};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/04__apache_log.kex\nSource md5: 5c2abee157 d 228b3e24d48c2163bfd\nSST states: 17\n");
}
void init()
{
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && (((next[0] == '.') || (('0' <= next[0]) && (next[0] <= '9'))) && 1)))
{
outputarray(const_1_9,48);
outputconst(next[0],8);
consume(1);
goto l1_10;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == '"') && 1)))
{
outputarray(const_1_0,72);
consume(1);
goto l1_14;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == '"') && 1)))
{
outputarray(const_1_6,56);
consume(1);
goto l1_13;
}
goto fail1;
l1_3: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_3;
}
if (((avail >= 2) && ((next[0] == '-') && (((next[1] == 9) || (next[1] == ' ')) && 1))))
{
outputarray(const_1_4,56);
outputconst(next[0],8);
consume(2);
goto l1_2;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputarray(const_1_4,56);
outputconst(next[0],8);
consume(1);
goto l1_16;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputarray(const_1_5,72);
outputconst(next[0],8);
consume(1);
goto l1_15;
}
goto fail1;
l1_5: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_5;
}
if (((avail >= 2) && ((next[0] == '"') && ((((0 <= next[1]) && (next[1] <= 9)) || (((11 <= next[1]) && (next[1] <= '!')) || (('#' <= next[1]) && (next[1] <= 255)))) && 1))))
{
outputarray(const_1_3,80);
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
consume(2);
goto l1_12;
}
goto fail1;
l1_6: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_6;
}
if (((avail >= 2) && ((next[0] == '[') && ((((0 <= next[1]) && (next[1] <= 9)) || (((11 <= next[1]) && (next[1] <= 92)) || (('^' <= next[1]) && (next[1] <= 255)))) && 1))))
{
outputarray(const_1_2,56);
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
consume(2);
goto l1_11;
}
goto fail1;
l1_7: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_7;
}
if (((avail >= 2) && ((next[0] == '-') && (((next[1] == 9) || (next[1] == ' ')) && 1))))
{
outputarray(const_1_1,88);
outputconst(next[0],8);
consume(2);
goto l1_6;
}
goto fail1;
l1_8: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_8;
}
if (((avail >= 2) && ((next[0] == '-') && (((next[1] == 9) || (next[1] == ' ')) && 1))))
{
outputarray(const_1_7,72);
outputconst(next[0],8);
consume(2);
goto l1_7;
}
goto fail1;
l1_9: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && (((next[0] == '.') || (('0' <= next[0]) && (next[0] <= '9'))) && 1)))
{
outputarray(const_1_9,48);
outputconst(next[0],8);
consume(1);
goto l1_10;
}
goto fail1;
l1_10: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_8;
}
if (((avail >= 1) && (((next[0] == '.') || (('0' <= next[0]) && (next[0] <= '9'))) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_10;
}
goto fail1;
l1_11: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= 92)) || (('^' <= next[0]) && (next[0] <= 255)))) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_11;
}
if (((avail >= 2) && ((next[0] == ']') && (((next[1] == 9) || (next[1] == ' ')) && 1))))
{
outputconst(next[0],8);
consume(2);
goto l1_5;
}
goto fail1;
l1_12: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= '!')) || (('#' <= next[0]) && (next[0] <= 255)))) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_12;
}
if (((avail >= 2) && ((next[0] == '"') && (((next[1] == 9) || (next[1] == ' ')) && 1))))
{
outputconst(next[0],8);
consume(2);
goto l1_4;
}
goto fail1;
l1_13: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= '!')) || (('#' <= next[0]) && (next[0] <= 255)))) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_13;
}
if (((avail >= 2) && ((next[0] == '"') && (((next[1] == 9) || (next[1] == ' ')) && 1))))
{
outputconst(next[0],8);
consume(2);
goto l1_1;
}
goto fail1;
l1_14: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= '!')) || (('#' <= next[0]) && (next[0] <= 255)))) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_14;
}
if (((avail >= 2) && (cmp(&next[0],(unsigned char *) """\x22""""\xa""",2) && 1)))
{
outputarray(const_1_8,24);
consume(2);
goto l1_9;
}
goto fail1;
l1_15: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_15;
}
goto fail1;
l1_16: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == 9) || (next[0] == ' ')) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_16;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,793 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
buffer_t buf_1;
buffer_t buf_2;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// \xaday:
const buffer_unit_t const_1_1[6] = {0xa,0x64,0x61,0x79,0x3a,0x20};
// \xahours:
const buffer_unit_t const_1_2[8] = {0xa,0x68,0x6f,0x75,0x72,0x73,0x3a,0x20};
// \xaminutes:
const buffer_unit_t const_1_3[10] = {0xa,0x6d,0x69,0x6e,0x75,0x74,0x65,0x73,0x3a,0x20};
// \xamonth:
const buffer_unit_t const_1_4[8] = {0xa,0x6d,0x6f,0x6e,0x74,0x68,0x3a,0x20};
// \xaseconds:
const buffer_unit_t const_1_5[10] = {0xa,0x73,0x65,0x63,0x6f,0x6e,0x64,0x73,0x3a,0x20};
// \xatz:
const buffer_unit_t const_1_6[5] = {0xa,0x74,0x7a,0x3a,0x20};
// Z\xa
const buffer_unit_t const_1_7[2] = {0x5a,0xa};
// year:
const buffer_unit_t const_1_8[6] = {0x79,0x65,0x61,0x72,0x3a,0x20};
// year: 0
const buffer_unit_t const_1_9[7] = {0x79,0x65,0x61,0x72,0x3a,0x20,0x30};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/05__datetime.kex\nSource md5: c45f984dab5249fecb87 e76fa5b3c1f\nSST states: 13\n");
}
void init()
{
init_buffer(&buf_1);
init_buffer(&buf_2);
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '0') && 1)))
{
outputarray(const_1_9,56);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((('1' <= next[0]) && (next[0] <= '9')) && 1)))
{
reset(&buf_2);
reset(&buf_1);
outputarray(const_1_8,48);
outputconst(next[0],8);
consume(1);
goto l1_12;
}
goto fail1;
l1_1: if (!readnext(4, 4))
{
goto fail1;
}
if (((avail >= 4) && ((('0' <= next[0]) && (next[0] <= '9')) && ((('0' <= next[1]) && (next[1] <= '9')) && ((('0' <= next[2]) && (next[2] <= '9')) && ((next[3] == '-') && 1))))))
{
for(i = 0; i < 3; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_4,64);
consume(4);
goto l1_6;
}
goto fail1;
l1_2: if (!readnext(2, 2))
{
goto fail1;
}
if (((avail >= 2) && ((('0' <= next[0]) && (next[0] <= '5')) && ((('0' <= next[1]) && (next[1] <= '9')) && 1))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_6,40);
consume(2);
goto l1_10;
}
goto fail1;
l1_3: if (!readnext(3, 3))
{
goto fail1;
}
if (((avail >= 3) && ((('0' <= next[0]) && (next[0] <= '5')) && ((('0' <= next[1]) && (next[1] <= '9')) && ((next[2] == ':') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_5,80);
consume(3);
goto l1_2;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_11;
}
goto fail1;
l1_5: if (!readnext(1, 5))
{
goto fail1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 5) && ((('0' <= next[1]) && (next[1] <= '9')) && ((('0' <= next[2]) && (next[2] <= '9')) && ((('0' <= next[3]) && (next[3] <= '9')) && ((next[4] == '-') && 1))))))
{
for(i = 0; i < 4; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_4,64);
consume(5);
goto l1_6;
}
outputconst(next[0],8);
consume(1);
goto l1_5;
}
goto fail1;
l1_6: if (!readnext(3, 3))
{
goto fail1;
}
if (((avail >= 3) && ((next[0] == '0') && ((('1' <= next[1]) && (next[1] <= '9')) && ((next[2] == '-') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_1,48);
consume(3);
goto l1_7;
}
if (((avail >= 3) && ((next[0] == '1') && ((('0' <= next[1]) && (next[1] <= '2')) && ((next[2] == '-') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_1,48);
consume(3);
goto l1_7;
}
goto fail1;
l1_7: if (!readnext(3, 3))
{
goto fail1;
}
if (((avail >= 3) && ((next[0] == '0') && ((('1' <= next[1]) && (next[1] <= '9')) && ((next[2] == 'T') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_2,64);
consume(3);
goto l1_9;
}
if (((avail >= 3) && ((('1' <= next[0]) && (next[0] <= '2')) && ((('0' <= next[1]) && (next[1] <= '9')) && ((next[2] == 'T') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_2,64);
consume(3);
goto l1_9;
}
if (((avail >= 3) && ((next[0] == '3') && ((('0' <= next[1]) && (next[1] <= '1')) && ((next[2] == 'T') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_2,64);
consume(3);
goto l1_9;
}
goto fail1;
l1_8: if (!readnext(5, 5))
{
goto fail1;
}
if (((avail >= 5) && ((('0' <= next[0]) && (next[0] <= '1')) && ((('0' <= next[1]) && (next[1] <= '9')) && ((next[2] == ':') && ((('0' <= next[3]) && (next[3] <= '5')) && ((('0' <= next[4]) && (next[4] <= '9')) && 1)))))))
{
for(i = 0; i < 5; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_0,8);
consume(5);
goto l1_4;
}
if (((avail >= 5) && ((next[0] == '2') && ((('0' <= next[1]) && (next[1] <= '3')) && ((next[2] == ':') && ((('0' <= next[3]) && (next[3] <= '5')) && ((('0' <= next[4]) && (next[4] <= '9')) && 1)))))))
{
for(i = 0; i < 5; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_0,8);
consume(5);
goto l1_4;
}
goto fail1;
l1_9: if (!readnext(3, 3))
{
goto fail1;
}
if (((avail >= 3) && ((('0' <= next[0]) && (next[0] <= '1')) && ((('0' <= next[1]) && (next[1] <= '9')) && ((next[2] == ':') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_3,80);
consume(3);
goto l1_3;
}
if (((avail >= 3) && ((next[0] == '2') && ((('0' <= next[1]) && (next[1] <= '3')) && ((next[2] == ':') && 1)))))
{
for(i = 0; i < 2; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_3,80);
consume(3);
goto l1_3;
}
goto fail1;
l1_10: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && (((next[0] == '+') || (next[0] == '-')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_8;
}
if (((avail >= 1) && ((next[0] == 'Z') && 1)))
{
outputarray(const_1_7,16);
consume(1);
goto l1_4;
}
goto fail1;
l1_11: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == '0') && 1)))
{
outputarray(const_1_9,56);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((('1' <= next[0]) && (next[0] <= '9')) && 1)))
{
reset(&buf_2);
append(&buf_2,next[0],8);
reset(&buf_1);
append(&buf_1,next[0],8);
outputarray(const_1_8,48);
consume(1);
goto l1_12;
}
goto fail1;
l1_12: if (!readnext(1, 5))
{
goto fail1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 3) && ((('0' <= next[1]) && (next[1] <= '9')) && ((('0' <= next[2]) && (next[2] <= '9')) && 1))))
{
if (((avail >= 4) && ((next[3] == '-') && 1)))
{
output(&buf_2);
for(i = 0; i < 3; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_4,64);
consume(4);
goto l1_6;
}
if (((avail >= 5) && ((('0' <= next[3]) && (next[3] <= '9')) && ((next[4] == '-') && 1))))
{
output(&buf_1);
for(i = 0; i < 4; i++)
{ outputconst(next[0 + i],8);
}
outputarray(const_1_4,64);
consume(5);
goto l1_6;
}
}
output(&buf_1);
outputconst(next[0],8);
consume(1);
goto l1_5;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,882 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
buffer_t buf_1;
buffer_t buf_2;
buffer_t buf_3;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
//
const buffer_unit_t const_1_1[1] = {0x20};
// -
const buffer_unit_t const_1_2[1] = {0x2d};
// .
const buffer_unit_t const_1_3[1] = {0x2e};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/06__email.kex\nSource md5: 437ac440bbbfc56a11b3965ce24849 0\nSST states: 11\n");
}
void init()
{
init_buffer(&buf_1);
init_buffer(&buf_2);
init_buffer(&buf_3);
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ' ')) || ((next[0] == '"') || ((('(' <= next[0]) && (next[0] <= ')')) || ((next[0] == ',') || ((next[0] == '.') || (((':' <= next[0]) && (next[0] <= '<')) || ((next[0] == '>') || ((('@' <= next[0]) && (next[0] <= ']')) || ((127 <= next[0]) && (next[0] <= 255))))))))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && (((next[0] == '!') || ((('#' <= next[0]) && (next[0] <= 39)) || ((('*' <= next[0]) && (next[0] <= '+')) || ((next[0] == '-') || ((('/' <= next[0]) && (next[0] <= '9')) || ((next[0] == '=') || ((next[0] == '?') || (('^' <= next[0]) && (next[0] <= '~'))))))))) && 1)))
{
reset(&buf_1);
appendarray(&buf_1,const_1_1,8);
append(&buf_1,next[0],8);
consume(1);
goto l1_3;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= '/')) || (((':' <= next[0]) && (next[0] <= '`')) || (('{' <= next[0]) && (next[0] <= 255))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && (((('0' <= next[0]) && (next[0] <= '9')) || (('a' <= next[0]) && (next[0] <= 'z'))) && 1)))
{
append(&buf_1,next[0],8);
consume(1);
goto l1_8;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || ((11 <= next[0]) && (next[0] <= 255))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
goto fail1;
l1_3: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ' ')) || ((next[0] == '"') || ((('(' <= next[0]) && (next[0] <= ')')) || ((next[0] == ',') || (((':' <= next[0]) && (next[0] <= '<')) || ((next[0] == '>') || ((('A' <= next[0]) && (next[0] <= ']')) || ((127 <= next[0]) && (next[0] <= 255)))))))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && (((next[0] == '!') || ((('#' <= next[0]) && (next[0] <= 39)) || ((('*' <= next[0]) && (next[0] <= '+')) || ((next[0] == '-') || ((('/' <= next[0]) && (next[0] <= '9')) || ((next[0] == '=') || ((next[0] == '?') || (('^' <= next[0]) && (next[0] <= '~'))))))))) && 1)))
{
append(&buf_1,next[0],8);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
if (((avail >= 2) && (((next[1] == '!') || ((('#' <= next[1]) && (next[1] <= 39)) || ((('*' <= next[1]) && (next[1] <= '+')) || ((next[1] == '-') || ((('/' <= next[1]) && (next[1] <= '9')) || ((next[1] == '=') || ((next[1] == '?') || (('^' <= next[1]) && (next[1] <= '~'))))))))) && 1)))
{
for(i = 0; i < 2; i++)
{ append(&buf_1,next[0 + i],8);
}
consume(2);
goto l1_5;
}
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == '@') && 1)))
{
appendarray(&buf_1,const_1_1,8);
consume(1);
goto l1_1;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ' ')) || ((next[0] == '"') || ((('(' <= next[0]) && (next[0] <= ')')) || ((next[0] == ',') || ((next[0] == '.') || (((':' <= next[0]) && (next[0] <= '<')) || ((next[0] == '>') || ((('@' <= next[0]) && (next[0] <= ']')) || ((127 <= next[0]) && (next[0] <= 255))))))))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && (((next[0] == '!') || ((('#' <= next[0]) && (next[0] <= 39)) || ((('*' <= next[0]) && (next[0] <= '+')) || ((next[0] == '-') || ((('/' <= next[0]) && (next[0] <= '9')) || ((next[0] == '=') || ((next[0] == '?') || (('^' <= next[0]) && (next[0] <= '~'))))))))) && 1)))
{
reset(&buf_1);
appendarray(&buf_1,const_1_1,8);
append(&buf_1,next[0],8);
consume(1);
goto l1_3;
}
goto fail1;
l1_5: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ' ')) || ((next[0] == '"') || ((('(' <= next[0]) && (next[0] <= ')')) || ((next[0] == ',') || (((':' <= next[0]) && (next[0] <= '<')) || ((next[0] == '>') || ((('A' <= next[0]) && (next[0] <= ']')) || ((127 <= next[0]) && (next[0] <= 255)))))))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && (((next[0] == '!') || ((('#' <= next[0]) && (next[0] <= 39)) || ((('*' <= next[0]) && (next[0] <= '+')) || ((next[0] == '-') || ((('/' <= next[0]) && (next[0] <= '9')) || ((next[0] == '=') || ((next[0] == '?') || (('^' <= next[0]) && (next[0] <= '~'))))))))) && 1)))
{
append(&buf_1,next[0],8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
if (((avail >= 2) && (((next[1] == '!') || ((('#' <= next[1]) && (next[1] <= 39)) || ((('*' <= next[1]) && (next[1] <= '+')) || ((next[1] == '-') || ((('/' <= next[1]) && (next[1] <= '9')) || ((next[1] == '=') || ((next[1] == '?') || (('^' <= next[1]) && (next[1] <= '~'))))))))) && 1)))
{
for(i = 0; i < 2; i++)
{ append(&buf_1,next[0 + i],8);
}
consume(2);
goto l1_5;
}
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == '@') && 1)))
{
appendarray(&buf_1,const_1_1,8);
consume(1);
goto l1_1;
}
goto fail1;
l1_6: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= '/')) || (((':' <= next[0]) && (next[0] <= '`')) || (('{' <= next[0]) && (next[0] <= 255))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && (((('0' <= next[0]) && (next[0] <= '9')) || (('a' <= next[0]) && (next[0] <= 'z'))) && 1)))
{
reset(&buf_3);
append(&buf_3,next[0],8);
reset(&buf_2);
append(&buf_2,next[0],8);
consume(1);
goto l1_10;
}
goto fail1;
l1_7: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ',')) || ((('.' <= next[0]) && (next[0] <= '/')) || (((':' <= next[0]) && (next[0] <= '`')) || (('{' <= next[0]) && (next[0] <= 255)))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == '-') && 1)))
{
appendarray(&buf_1,const_1_2,8);
consume(1);
goto l1_7;
}
if (((avail >= 1) && (((('0' <= next[0]) && (next[0] <= '9')) || (('a' <= next[0]) && (next[0] <= 'z'))) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
for(i = 0; i < 2; i++)
{ append(&buf_1,next[0 + i],8);
}
consume(2);
goto l1_6;
}
append(&buf_1,next[0],8);
consume(1);
goto l1_7;
}
goto fail1;
l1_8: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ',')) || ((next[0] == '/') || (((':' <= next[0]) && (next[0] <= '`')) || (('{' <= next[0]) && (next[0] <= 255)))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == '-') && 1)))
{
appendarray(&buf_1,const_1_2,8);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
appendarray(&buf_1,const_1_3,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && (((('0' <= next[0]) && (next[0] <= '9')) || (('a' <= next[0]) && (next[0] <= 'z'))) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
for(i = 0; i < 2; i++)
{ append(&buf_1,next[0 + i],8);
}
consume(2);
goto l1_6;
}
append(&buf_1,next[0],8);
consume(1);
goto l1_7;
}
goto fail1;
l1_9: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ',')) || ((('.' <= next[0]) && (next[0] <= '/')) || (((':' <= next[0]) && (next[0] <= '`')) || (('{' <= next[0]) && (next[0] <= 255)))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == '-') && 1)))
{
appendarray(&buf_3,const_1_2,8);
appendarray(&buf_2,const_1_2,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && (((('0' <= next[0]) && (next[0] <= '9')) || (('a' <= next[0]) && (next[0] <= 'z'))) && 1)))
{
if (((avail >= 2) && ((next[1] == 10) && 1)))
{
output(&buf_1);
output(&buf_3);
outputconst(next[0],8);
outputarray(const_1_0,8);
consume(2);
goto l1_4;
}
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
concat(&buf_1,&buf_2);
for(i = 0; i < 2; i++)
{ append(&buf_1,next[0 + i],8);
}
consume(2);
goto l1_6;
}
append(&buf_3,next[0],8);
append(&buf_2,next[0],8);
consume(1);
goto l1_9;
}
goto fail1;
l1_10: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((((0 <= next[0]) && (next[0] <= 9)) || (((11 <= next[0]) && (next[0] <= ',')) || ((next[0] == '/') || (((':' <= next[0]) && (next[0] <= '`')) || (('{' <= next[0]) && (next[0] <= 255)))))) && 1)))
{
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
output(&buf_3);
outputarray(const_1_0,8);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == '-') && 1)))
{
appendarray(&buf_3,const_1_2,8);
appendarray(&buf_2,const_1_2,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
concat(&buf_1,&buf_2);
appendarray(&buf_1,const_1_3,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && (((('0' <= next[0]) && (next[0] <= '9')) || (('a' <= next[0]) && (next[0] <= 'z'))) && 1)))
{
if (((avail >= 2) && ((next[1] == 10) && 1)))
{
output(&buf_1);
output(&buf_3);
outputconst(next[0],8);
outputarray(const_1_0,8);
consume(2);
goto l1_4;
}
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
concat(&buf_1,&buf_2);
for(i = 0; i < 2; i++)
{ append(&buf_1,next[0 + i],8);
}
consume(2);
goto l1_6;
}
append(&buf_3,next[0],8);
append(&buf_2,next[0],8);
consume(1);
goto l1_9;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,826 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// ,
const buffer_unit_t const_1_1[1] = {0x2c};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/07__ipv4.kex\nSource md5: c1c35f349c1fef94586727bc137db489\nSST states: 17\n");
}
void init()
{
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_8;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_5;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_6;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_7;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
outputconst(next[0],8);
consume(1);
goto l1_8;
}
goto fail1;
l1_5: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == 10) && 1)))
{
outputconst(next[0],8);
outputarray(const_1_0,8);
consume(2);
goto l1_4;
}
outputconst(next[0],8);
consume(1);
goto l1_9;
}
goto fail1;
l1_6: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_1;
}
outputconst(next[0],8);
consume(1);
goto l1_10;
}
goto fail1;
l1_7: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_2;
}
outputconst(next[0],8);
consume(1);
goto l1_11;
}
goto fail1;
l1_8: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_3;
}
outputconst(next[0],8);
consume(1);
goto l1_12;
}
goto fail1;
l1_9: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == 10) && 1)))
{
outputconst(next[0],8);
outputarray(const_1_0,8);
consume(2);
goto l1_4;
}
outputconst(next[0],8);
consume(1);
goto l1_13;
}
goto fail1;
l1_10: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_1;
}
outputconst(next[0],8);
consume(1);
goto l1_14;
}
goto fail1;
l1_11: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_2;
}
outputconst(next[0],8);
consume(1);
goto l1_15;
}
goto fail1;
l1_12: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((('0' <= next[0]) && (next[0] <= '9')) && 1)))
{
if (((avail >= 2) && ((next[1] == '.') && 1)))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_3;
}
outputconst(next[0],8);
consume(1);
goto l1_16;
}
goto fail1;
l1_13: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_4;
}
if (((avail >= 2) && ((('0' <= next[0]) && (next[0] <= '9')) && ((next[1] == 10) && 1))))
{
outputconst(next[0],8);
outputarray(const_1_0,8);
consume(2);
goto l1_4;
}
goto fail1;
l1_14: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_1;
}
if (((avail >= 2) && ((('0' <= next[0]) && (next[0] <= '9')) && ((next[1] == '.') && 1))))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_1;
}
goto fail1;
l1_15: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_2;
}
if (((avail >= 2) && ((('0' <= next[0]) && (next[0] <= '9')) && ((next[1] == '.') && 1))))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_2;
}
goto fail1;
l1_16: if (!readnext(1, 2))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == '.') && 1)))
{
outputarray(const_1_1,8);
consume(1);
goto l1_3;
}
if (((avail >= 2) && ((('0' <= next[0]) && (next[0] <= '9')) && ((next[1] == '.') && 1))))
{
outputconst(next[0],8);
outputarray(const_1_1,8);
consume(2);
goto l1_3;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,595 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// A\xa
const buffer_unit_t const_1_1[2] = {0x41,0xa};
// Aa
const buffer_unit_t const_1_2[2] = {0x41,0x61};
// Bb
const buffer_unit_t const_1_3[2] = {0x42,0x62};
// a
const buffer_unit_t const_1_4[1] = {0x61};
// b
const buffer_unit_t const_1_5[1] = {0x62};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/10__alt1_2.kex\nSource md5: 933017c27ef6b9d9873167f64a593afc\nSST states: 4\n");
}
void init()
{
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_2,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_3,16);
consume(1);
goto l1_2;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_4,8);
consume(1);
goto l1_1;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_5,8);
consume(1);
goto l1_2;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_2,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_3,16);
consume(1);
goto l1_2;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,661 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// A\xa
const buffer_unit_t const_1_1[2] = {0x41,0xa};
// Aa
const buffer_unit_t const_1_2[2] = {0x41,0x61};
// Bb
const buffer_unit_t const_1_3[2] = {0x42,0x62};
// Cc
const buffer_unit_t const_1_4[2] = {0x43,0x63};
// Dd
const buffer_unit_t const_1_5[2] = {0x44,0x64};
// a
const buffer_unit_t const_1_6[1] = {0x61};
// b
const buffer_unit_t const_1_7[1] = {0x62};
// c
const buffer_unit_t const_1_8[1] = {0x63};
// d
const buffer_unit_t const_1_9[1] = {0x64};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/11__alt1_4.kex\nSource md5: a46aa0b6cb7b64dabc59 919 e23de80\nSST states: 6\n");
}
void init()
{
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_2,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_3,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_4;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_1;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_7,8);
consume(1);
goto l1_2;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_8,8);
consume(1);
goto l1_3;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_9,8);
consume(1);
goto l1_4;
}
goto fail1;
l1_5: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_2,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_3,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_4;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,793 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// A\xa
const buffer_unit_t const_1_1[2] = {0x41,0xa};
// Aa
const buffer_unit_t const_1_2[2] = {0x41,0x61};
// Bb
const buffer_unit_t const_1_3[2] = {0x42,0x62};
// Cc
const buffer_unit_t const_1_4[2] = {0x43,0x63};
// Dd
const buffer_unit_t const_1_5[2] = {0x44,0x64};
// Ee
const buffer_unit_t const_1_6[2] = {0x45,0x65};
// Ff
const buffer_unit_t const_1_7[2] = {0x46,0x66};
// Gg
const buffer_unit_t const_1_8[2] = {0x47,0x67};
// Hh
const buffer_unit_t const_1_9[2] = {0x48,0x68};
// a
const buffer_unit_t const_1_10[1] = {0x61};
// b
const buffer_unit_t const_1_11[1] = {0x62};
// c
const buffer_unit_t const_1_12[1] = {0x63};
// d
const buffer_unit_t const_1_13[1] = {0x64};
// e
const buffer_unit_t const_1_14[1] = {0x65};
// f
const buffer_unit_t const_1_15[1] = {0x66};
// g
const buffer_unit_t const_1_16[1] = {0x67};
// h
const buffer_unit_t const_1_17[1] = {0x68};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/12__alt1_8.kex\nSource md5: ba40f7ea 99c54e73bc1dee39826 aef\nSST states: 10\n");
}
void init()
{
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_2,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_3,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'e') && 1)))
{
outputarray(const_1_6,16);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'f') && 1)))
{
outputarray(const_1_7,16);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'g') && 1)))
{
outputarray(const_1_8,16);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'h') && 1)))
{
outputarray(const_1_9,16);
consume(1);
goto l1_8;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_10,8);
consume(1);
goto l1_1;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_11,8);
consume(1);
goto l1_2;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_12,8);
consume(1);
goto l1_3;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_13,8);
consume(1);
goto l1_4;
}
goto fail1;
l1_5: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'e') && 1)))
{
outputarray(const_1_14,8);
consume(1);
goto l1_5;
}
goto fail1;
l1_6: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'f') && 1)))
{
outputarray(const_1_15,8);
consume(1);
goto l1_6;
}
goto fail1;
l1_7: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'g') && 1)))
{
outputarray(const_1_16,8);
consume(1);
goto l1_7;
}
goto fail1;
l1_8: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'h') && 1)))
{
outputarray(const_1_17,8);
consume(1);
goto l1_8;
}
goto fail1;
l1_9: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_2,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_3,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'e') && 1)))
{
outputarray(const_1_6,16);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'f') && 1)))
{
outputarray(const_1_7,16);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'g') && 1)))
{
outputarray(const_1_8,16);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'h') && 1)))
{
outputarray(const_1_9,16);
consume(1);
goto l1_8;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,657 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
buffer_t buf_1;
buffer_t buf_2;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// A\xa
const buffer_unit_t const_1_1[2] = {0x41,0xa};
// AA\xa
const buffer_unit_t const_1_2[3] = {0x41,0x41,0xa};
// ABb
const buffer_unit_t const_1_3[3] = {0x41,0x42,0x62};
// Aa
const buffer_unit_t const_1_4[2] = {0x41,0x61};
// Bb
const buffer_unit_t const_1_5[2] = {0x42,0x62};
// a
const buffer_unit_t const_1_6[1] = {0x61};
// b
const buffer_unit_t const_1_7[1] = {0x62};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/13__alt2_2.kex\nSource md5: 8e558b 4654ac181234bab147e994f1d\nSST states: 6\n");
}
void init()
{
init_buffer(&buf_1);
init_buffer(&buf_2);
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_2,24);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_5,16);
reset(&buf_1);
appendarray(&buf_1,const_1_3,24);
consume(1);
goto l1_4;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_3;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_2;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_7,8);
consume(1);
goto l1_3;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
output(&buf_2);
outputarray(const_1_4,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
appendarray(&buf_2,const_1_7,8);
appendarray(&buf_1,const_1_7,8);
consume(1);
goto l1_4;
}
goto fail1;
l1_5: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_2,24);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_5,16);
reset(&buf_1);
appendarray(&buf_1,const_1_3,24);
consume(1);
goto l1_4;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
@@ -0,0 +1,845 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
buffer_t buf_1;
buffer_t buf_2;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// A\xa
const buffer_unit_t const_1_1[2] = {0x41,0xa};
// AA\xa
const buffer_unit_t const_1_2[3] = {0x41,0x41,0xa};
// ABb
const buffer_unit_t const_1_3[3] = {0x41,0x42,0x62};
// ACc
const buffer_unit_t const_1_4[3] = {0x41,0x43,0x63};
// ADd
const buffer_unit_t const_1_5[3] = {0x41,0x44,0x64};
// Aa
const buffer_unit_t const_1_6[2] = {0x41,0x61};
// Bb
const buffer_unit_t const_1_7[2] = {0x42,0x62};
// Cc
const buffer_unit_t const_1_8[2] = {0x43,0x63};
// Dd
const buffer_unit_t const_1_9[2] = {0x44,0x64};
// a
const buffer_unit_t const_1_10[1] = {0x61};
// b
const buffer_unit_t const_1_11[1] = {0x62};
// c
const buffer_unit_t const_1_12[1] = {0x63};
// d
const buffer_unit_t const_1_13[1] = {0x64};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/14__alt2_4.kex\nSource md5: a7516a1d89d83c9d3ebcb1332232 4b6\nSST states: 10\n");
}
void init()
{
init_buffer(&buf_1);
init_buffer(&buf_2);
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_2,24);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_7,16);
reset(&buf_1);
appendarray(&buf_1,const_1_3,24);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_8,16);
reset(&buf_1);
appendarray(&buf_1,const_1_4,24);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_9,16);
reset(&buf_1);
appendarray(&buf_1,const_1_5,24);
consume(1);
goto l1_8;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_10,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_7,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_8,16);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_9,16);
consume(1);
goto l1_5;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_10,8);
consume(1);
goto l1_2;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_11,8);
consume(1);
goto l1_3;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
outputarray(const_1_12,8);
consume(1);
goto l1_4;
}
goto fail1;
l1_5: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
outputarray(const_1_13,8);
consume(1);
goto l1_5;
}
goto fail1;
l1_6: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
output(&buf_2);
outputarray(const_1_6,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
appendarray(&buf_2,const_1_11,8);
appendarray(&buf_1,const_1_11,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
output(&buf_2);
outputarray(const_1_8,16);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
output(&buf_2);
outputarray(const_1_9,16);
consume(1);
goto l1_5;
}
goto fail1;
l1_7: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
output(&buf_2);
outputarray(const_1_6,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
output(&buf_2);
outputarray(const_1_7,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
appendarray(&buf_2,const_1_12,8);
appendarray(&buf_1,const_1_12,8);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
output(&buf_2);
outputarray(const_1_9,16);
consume(1);
goto l1_5;
}
goto fail1;
l1_8: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
outputarray(const_1_0,8);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
output(&buf_2);
outputarray(const_1_6,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
output(&buf_2);
outputarray(const_1_7,16);
consume(1);
goto l1_3;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
output(&buf_2);
outputarray(const_1_8,16);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
appendarray(&buf_2,const_1_13,8);
appendarray(&buf_1,const_1_13,8);
consume(1);
goto l1_8;
}
goto fail1;
l1_9: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_2,24);
consume(1);
goto l1_9;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_7,16);
reset(&buf_1);
appendarray(&buf_1,const_1_3,24);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'c') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_8,16);
reset(&buf_1);
appendarray(&buf_1,const_1_4,24);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'd') && 1)))
{
reset(&buf_2);
appendarray(&buf_2,const_1_9,16);
reset(&buf_1);
appendarray(&buf_1,const_1_5,24);
consume(1);
goto l1_8;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,803 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
buffer_t buf_1;
buffer_t buf_2;
buffer_t buf_3;
buffer_t buf_4;
buffer_t buf_5;
buffer_t buf_6;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// A
const buffer_unit_t const_1_1[1] = {0x41};
// AA
const buffer_unit_t const_1_2[2] = {0x41,0x41};
// AAA\xa
const buffer_unit_t const_1_3[4] = {0x41,0x41,0x41,0xa};
// AAAA\xa
const buffer_unit_t const_1_4[5] = {0x41,0x41,0x41,0x41,0xa};
// ABb
const buffer_unit_t const_1_5[3] = {0x41,0x42,0x62};
// Aa
const buffer_unit_t const_1_6[2] = {0x41,0x61};
// Bb
const buffer_unit_t const_1_7[2] = {0x42,0x62};
// a
const buffer_unit_t const_1_8[1] = {0x61};
// b
const buffer_unit_t const_1_9[1] = {0x62};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/16__alt4_2.kex\nSource md5: 1216b4916935f0 0a1284315ccc3d519\nSST states: 10\n");
}
void init()
{
init_buffer(&buf_1);
init_buffer(&buf_2);
init_buffer(&buf_3);
init_buffer(&buf_4);
init_buffer(&buf_5);
init_buffer(&buf_6);
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_4,40);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_6);
appendarray(&buf_6,const_1_7,16);
reset(&buf_5);
appendarray(&buf_5,const_1_7,16);
reset(&buf_4);
appendarray(&buf_4,const_1_7,16);
reset(&buf_3);
appendarray(&buf_3,const_1_5,24);
consume(1);
goto l1_9;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_3,32);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_8,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_5);
appendarray(&buf_5,const_1_7,16);
reset(&buf_4);
appendarray(&buf_4,const_1_7,16);
reset(&buf_2);
appendarray(&buf_2,const_1_5,24);
consume(1);
goto l1_8;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_8,8);
consume(1);
goto l1_2;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_9,8);
consume(1);
goto l1_3;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
appendarray(&buf_4,const_1_8,8);
appendarray(&buf_1,const_1_8,8);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
output(&buf_4);
outputarray(const_1_7,16);
consume(1);
goto l1_3;
}
goto fail1;
l1_5: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
output(&buf_1);
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
output(&buf_4);
outputarray(const_1_6,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
appendarray(&buf_4,const_1_9,8);
appendarray(&buf_1,const_1_9,8);
consume(1);
goto l1_5;
}
goto fail1;
l1_6: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_4,40);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,16);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
reset(&buf_6);
appendarray(&buf_6,const_1_7,16);
reset(&buf_5);
appendarray(&buf_5,const_1_7,16);
reset(&buf_4);
appendarray(&buf_4,const_1_7,16);
reset(&buf_3);
appendarray(&buf_3,const_1_5,24);
consume(1);
goto l1_9;
}
goto fail1;
l1_7: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,8);
output(&buf_2);
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
appendarray(&buf_5,const_1_8,8);
appendarray(&buf_4,const_1_8,8);
appendarray(&buf_2,const_1_8,8);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
appendarray(&buf_4,const_1_7,16);
reset(&buf_1);
appendarray(&buf_1,const_1_1,8);
concat(&buf_1,&buf_5);
appendarray(&buf_1,const_1_7,16);
consume(1);
goto l1_5;
}
goto fail1;
l1_8: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,8);
output(&buf_2);
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
appendarray(&buf_4,const_1_6,16);
reset(&buf_1);
appendarray(&buf_1,const_1_1,8);
concat(&buf_1,&buf_5);
appendarray(&buf_1,const_1_6,16);
consume(1);
goto l1_4;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
appendarray(&buf_5,const_1_9,8);
appendarray(&buf_4,const_1_9,8);
appendarray(&buf_2,const_1_9,8);
consume(1);
goto l1_8;
}
goto fail1;
l1_9: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_2,16);
output(&buf_3);
outputarray(const_1_0,8);
consume(1);
goto l1_6;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
appendarray(&buf_5,const_1_6,16);
appendarray(&buf_4,const_1_6,16);
reset(&buf_2);
appendarray(&buf_2,const_1_1,8);
concat(&buf_2,&buf_6);
appendarray(&buf_2,const_1_6,16);
consume(1);
goto l1_7;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
appendarray(&buf_6,const_1_9,8);
appendarray(&buf_5,const_1_9,8);
appendarray(&buf_4,const_1_9,8);
appendarray(&buf_3,const_1_9,8);
consume(1);
goto l1_9;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,651 @@
#define NUM_PHASES 1
#define BUFFER_UNIT_T uint8_t
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/time.h>
#ifdef __APPLE__
# include <mach-o/dyld.h>
#endif
#define RETC_PRINT_USAGE 1
#define RETC_PRINT_INFO 2
#define OUTBUFFER_SIZE (16*1024)
#define INBUFFER_SIZE (16*1024)
#define INITIAL_BUFFER_SIZE (4096*8)
#define OUTBUFFER_STACK_SIZE (1024)
#ifdef FLAG_NOINLINE
#define INLINE static
#endif
#ifndef INLINE
#define INLINE static inline
#endif
#ifndef BUFFER_UNIT_T
#warning "BUFFER_UNIT_T not defined. Falling back to default 'uint8_t'"
#define BUFFER_UNIT_T uint8_t
#endif
#ifndef NUM_PHASES
#error "NUM_PHASES not defined."
#endif
#ifndef OUTSTREAM
#define OUTSTREAM stdout
#endif
// Order of descriptors provided by pipe()
#define READ_FD 0
#define WRITE_FD 1
typedef BUFFER_UNIT_T buffer_unit_t;
typedef struct {
buffer_unit_t *data;
size_t size; /* size in bytes */
size_t bitpos; /* bit offset from data */
} buffer_t;
#define BUFFER_UNIT_SIZE (sizeof(buffer_unit_t))
#define BUFFER_UNIT_BITS (BUFFER_UNIT_SIZE * 8)
unsigned char *next;
buffer_t outbuf;
buffer_t *outbuf_ptr;
size_t count = 0;
unsigned char inbuf[INBUFFER_SIZE*2];
size_t in_size = 0;
int in_cursor = 0;
#define avail (in_size - in_cursor)
// Output buffer stack
typedef struct {
buffer_t **data;
size_t capacity;
size_t size;
} buf_stack;
buf_stack outbuf_stack;
void pushoutbuf(buffer_t *buf) {
if (outbuf_stack.size == outbuf_stack.capacity) {
outbuf_stack.capacity *= 2;
outbuf_stack.data = realloc(outbuf_stack.data, outbuf_stack.capacity*sizeof(buffer_t *));
}
outbuf_stack.data[outbuf_stack.size++] = outbuf_ptr;
outbuf_ptr = buf;
}
void popoutbuf() {
if (outbuf_stack.size <= 0) {
fprintf(stderr, "Error: Tried popping an empty buffer stack");
exit(1);
}
outbuf_ptr = outbuf_stack.data[--outbuf_stack.size];
}
void init_outbuf_stack()
{
outbuf_ptr = &outbuf;
outbuf_stack.size = 0;
outbuf_stack.capacity = OUTBUFFER_STACK_SIZE;
outbuf_stack.data = malloc(OUTBUFFER_STACK_SIZE*sizeof(buffer_t *));
}
// Program interface
void printCompilationInfo();
void init();
void match(int phase);
void buf_flush(buffer_t *buf)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
// If we do not have a single complete word to flush, return.
// Not just an optimization! The zeroing logic below assumes word_index > 0.
if (word_index == 0)
{
return;
}
if (fwrite(buf->data, BUFFER_UNIT_SIZE, word_index, OUTSTREAM) == -1)
{
fprintf(stderr, "Error writing to output stream.\n");
exit(1);
}
// Since partially written words are not flushed, they need to be moved to the
// beginning of the buffer.
if (buf->bitpos % BUFFER_UNIT_BITS != 0)
{
buf->data[0] = buf->data[word_index];
}
else
{
// If we flushed everything, re-establish the invariant that the word at the
// cursor is garbage-free by simply zeroing it.
buf->data[0] = 0;
}
// Rewind cursor
buf->bitpos = buf->bitpos - word_index * BUFFER_UNIT_BITS;
}
// Write first 'bits' of 'w' to 'buf', starting from the MOST significant bit.
// Precondition: Remaining bits of 'w' must be zero.
INLINE
bool buf_writeconst(buffer_t *buf, buffer_unit_t w, size_t bits)
{
size_t word_index = buf->bitpos / BUFFER_UNIT_BITS;
size_t offset = buf->bitpos % BUFFER_UNIT_BITS;
size_t bits_available = BUFFER_UNIT_BITS - offset;
#ifdef FLAG_WORDALIGNED
buf->data[word_index] = w;
#else
buf->data[word_index] |= w >> offset;
// test for offset > 0 important; shifting by the word size is undefined behaviour.
buf->data[word_index+1] = (offset == 0) ? 0 : (w << bits_available);
#endif
buf->bitpos += bits;
// Is cursor in last word?
return (buf->bitpos >= buf->size * 8 - BUFFER_UNIT_BITS);
}
void buf_resize(buffer_t *buf, size_t shift)
{
size_t new_size = buf->size << shift;
buffer_unit_t *data2 = calloc(new_size, 1);
memcpy(data2, buf->data, buf->size);
free(buf->data);
buf->data = data2;
buf->size = new_size;
}
INLINE
void buf_writearray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
if (dst->bitpos % BUFFER_UNIT_BITS == 0)
{
int count = (bits / BUFFER_UNIT_BITS) + (bits % BUFFER_UNIT_BITS ? 1 : 0);
memcpy(&dst->data[dst->bitpos / BUFFER_UNIT_BITS], arr, count * BUFFER_UNIT_SIZE);
dst->bitpos += bits;
dst->data[dst->bitpos / BUFFER_UNIT_BITS] = 0;
} else
{
int word_index = 0;
for (word_index = 0; word_index < bits / BUFFER_UNIT_BITS; word_index++)
{
buf_writeconst(dst, arr[word_index], BUFFER_UNIT_BITS);
}
if (bits % BUFFER_UNIT_BITS != 0)
{
buf_writeconst(dst, arr[word_index], bits % BUFFER_UNIT_BITS);
}
}
}
INLINE
void reset(buffer_t *buf)
{
buf->data[0] = 0;
buf->bitpos = 0;
}
void init_buffer(buffer_t *buf)
{
buf->data = malloc(INITIAL_BUFFER_SIZE);
buf->size = INITIAL_BUFFER_SIZE;
buf->bitpos = 0;
buf->data[0] = 0;
}
void destroy_buffer(buffer_t *buf)
{
if (buf->data != NULL)
free(buf->data);
buf->data = NULL;
}
INLINE
void outputconst(buffer_unit_t w, size_t bits)
{
if (buf_writeconst(outbuf_ptr, w, bits))
{
if (outbuf_stack.size == 0)
{
buf_flush(outbuf_ptr);
}
}
}
INLINE
void appendarray(buffer_t *dst, const buffer_unit_t *arr, size_t bits)
{
size_t total_bits = dst->bitpos + bits;
if (total_bits >= (dst->size - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
size_t shift = 1;
while (total_bits >= ((dst->size << shift) - 1) * BUFFER_UNIT_BITS * BUFFER_UNIT_SIZE)
{
shift++;
}
buf_resize(dst, shift);
}
buf_writearray(dst, arr, bits);
}
INLINE
void append(buffer_t *buf, buffer_unit_t w, size_t bits)
{
if (buf_writeconst(buf, w, bits))
{
buf_resize(buf, 1);
}
}
INLINE
void concat(buffer_t *dst, buffer_t *src)
{
appendarray(dst, src->data, src->bitpos);
}
INLINE
void outputarray(const buffer_unit_t *arr, size_t bits)
{
int word_count = bits / BUFFER_UNIT_BITS;
// Write completed words
size_t word_index = 0;
for (word_index = 0; word_index < word_count; word_index++)
{
outputconst(arr[word_index], BUFFER_UNIT_BITS);
}
int remaining = bits % BUFFER_UNIT_BITS;
if (remaining != 0)
{
outputconst(arr[bits / BUFFER_UNIT_BITS], remaining);
}
}
INLINE
void output(buffer_t *buf)
{
outputarray(buf->data, buf->bitpos);
}
INLINE
void consume(int c)
{
count += c;
in_cursor += c;
next += c;
}
INLINE
int readnext(int minCount, int maxCount)
{
// We can always take epsilon transitions
if (minCount == 0) return 1;
if (avail < maxCount)
{
int remaining = avail;
memmove(&inbuf[INBUFFER_SIZE - remaining], &inbuf[INBUFFER_SIZE+in_cursor], remaining);
in_cursor = -remaining;
in_size = fread(&inbuf[INBUFFER_SIZE], 1, INBUFFER_SIZE, stdin);
}
if (avail < minCount)
{
return 0;
}
next = &inbuf[INBUFFER_SIZE+in_cursor];
return 1;
}
INLINE
int cmp(unsigned char *str1, unsigned char *str2, int l)
{
int i = 0;
for (i = 0; i < l; i++)
{
if (str1[i] != str2[i])
return 0;
}
return 1;
}
void printUsage(char *name)
{
fprintf(stdout, "Normal usage: %s < infile > outfile\n", name);
fprintf(stdout, "- \"%s\": reads from stdin and writes to stdout.\n", name);
fprintf(stdout, "- \"%s -i\": prints compilation info.\n", name);
fprintf(stdout, "- \"%s -t\": runs normally, but prints timing to stderr.\n", name);
}
void flush_outbuf()
{
if (outbuf.bitpos % BUFFER_UNIT_BITS != 0)
{
outputconst(0, BUFFER_UNIT_BITS);
}
if (outbuf_stack.size > 0)
{
fprintf(stderr, "Error: buffer stack ended non-empty\n");
exit(1);
}
buf_flush(&outbuf);
}
void init_outbuf()
{
outbuf.size = OUTBUFFER_SIZE + BUFFER_UNIT_SIZE;
outbuf.data = malloc(outbuf.size);
reset(&outbuf);
init_outbuf_stack();
}
void run(int phase)
{
init_outbuf();
init();
match(phase);
flush_outbuf();
}
#ifndef FLAG_NOMAIN
static struct option long_options[] = {
{ "phase", required_argument, 0, 'p' },
{ 0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
bool do_timing = false;
int c;
int option_index = 0;
int phase;
bool do_phase = false;
while ((c = getopt_long (argc, argv, "ihtp:", long_options, &option_index)) != -1)
{
switch (c)
{
case 'i':
printCompilationInfo();
return RETC_PRINT_INFO;
case 't':
do_timing = true;
break;
case 'p':
phase = atoi(optarg);
do_phase = true;
break;
case 'h':
default:
printUsage(argv[0]);
return RETC_PRINT_USAGE;
}
}
struct timeval time_before, time_after, time_result;
long int millis;
if(do_timing)
{
gettimeofday(&time_before, NULL);
}
if (do_phase)
{
run(phase);
}
else
{
// set up a pipeline
// stdin -> prog --phase 1 -> prog --phase 2 -> ... -> prog --phase n -> stdout
int orig_stdout = dup(STDOUT_FILENO);
int pipes[NUM_PHASES-1][2];
int i;
for (i = 1; i < NUM_PHASES; i++)
{
if (i != 1) close(pipes[i-2][WRITE_FD]);
if (pipe(pipes[i-1]) != 0)
{
fprintf(stderr, "Error creating pipe %d.", i);
return 1;
}
dup2(pipes[i-1][WRITE_FD], STDOUT_FILENO);
if (! fork())
{
close(orig_stdout);
close(pipes[i-1][READ_FD]);
// Should use snprintf, but I assume something else will break before we hit 10^19 phases.
char phase[20] = {0};
sprintf(phase, "%d", i);
char *args[] = { argv[0], "--phase", phase, 0 };
return main(3, args);
}
close(STDIN_FILENO);
dup2(pipes[i-1][READ_FD], STDIN_FILENO);
}
#if NUM_PHASES>1
close(pipes[NUM_PHASES-2][WRITE_FD]);
dup2(orig_stdout, STDOUT_FILENO);
#endif
// Run last phase in-process
run(NUM_PHASES);
}
if (do_timing)
{
gettimeofday(&time_after, NULL);
timersub(&time_after, &time_before, &time_result);
// A timeval contains seconds and microseconds.
millis = time_result.tv_sec * 1000 + time_result.tv_usec / 1000;
fprintf(stderr, "time (ms): %ld\n", millis);
}
return 0;
}
#endif
/* no tables */
buffer_t buf_0;
// \xa
const buffer_unit_t const_1_0[1] = {0xa};
// .\xa
const buffer_unit_t const_1_1[2] = {0x2e,0xa};
// ..\xa
const buffer_unit_t const_1_2[3] = {0x2e,0x2e,0xa};
// ...\xa
const buffer_unit_t const_1_3[4] = {0x2e,0x2e,0x2e,0xa};
// .a
const buffer_unit_t const_1_4[2] = {0x2e,0x61};
// .b
const buffer_unit_t const_1_5[2] = {0x2e,0x62};
// a
const buffer_unit_t const_1_6[1] = {0x61};
// b
const buffer_unit_t const_1_7[1] = {0x62};
void printCompilationInfo()
{
fprintf(stdout, "No object file generated!\nOptions:\nSST optimization level: 3\nWord size: UInt8T\nIdentity tables removed: False\n\nSource file: ../../../benchmarks/submatch_dfa_aot/src/kleenex/20__cat2_0.kex\nSource md5: 2a1c6fa6b7682bb74d 0bddd4dcf7a51\nSST states: 6\n");
}
void init()
{
}
void match1()
{
int i = 0;
goto l1_0;
l1_0: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_3,32);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_3;
}
goto fail1;
l1_1: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_3,32);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_3;
}
goto fail1;
l1_2: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_1,16);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_4;
}
goto fail1;
l1_3: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_2,24);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_4,16);
consume(1);
goto l1_2;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_7,8);
consume(1);
goto l1_3;
}
goto fail1;
l1_4: if (!readnext(1, 1))
{
goto fail1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_0,8);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_7,8);
consume(1);
goto l1_4;
}
goto fail1;
l1_5: if (!readnext(1, 1))
{
goto accept1;
}
if (((avail >= 1) && ((next[0] == 10) && 1)))
{
outputarray(const_1_3,32);
consume(1);
goto l1_5;
}
if (((avail >= 1) && ((next[0] == 'a') && 1)))
{
outputarray(const_1_6,8);
consume(1);
goto l1_1;
}
if (((avail >= 1) && ((next[0] == 'b') && 1)))
{
outputarray(const_1_5,16);
consume(1);
goto l1_3;
}
goto fail1;
accept1:
return;
fail1:
fprintf(stderr, "Match error at input symbol %zu!\n", count);
exit(1);
}
void match(int phase)
{
switch(phase) {
case 1: match1(); break;
default:
fprintf(stderr, "Invalid phase: %d given\n", phase);
exit(1);
}
}
File diff suppressed because it is too large Load Diff

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