text:
"""
   Copyright 2010 Sami Dalouche

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""

import os

class DeleteImagesCommand(object):
    """ Coordinates the deletion of an image metadata and files """

    def __init__(self, image_metadata_repository, session_template, path_generator, fetch_items_callback):
        """ Initializes a Delete Images Command with the following parameters
            @param image_metadata_repository: the repository for image metadata
            @param session_template: the db session template
            @param path_generator: a PathGenerator instance
            @param fetch_items_callback: some function that will return a list of image metadata

        """
        self.__image_metadata_repository = image_metadata_repository
        self.__path_generator = path_generator
        self.__session_template = session_template
        self.__fetch_items_callback = fetch_items_callback

    def __cleanup_in_session(self):
        items = self.__fetch_items_callback()
        for i in items:
            os.remove(i.associated_image_path(self.__path_generator).absolute())
            self.__image_metadata_repository.delete(i)

    def execute(self):
        def execute_in_session(session):
            self.__cleanup_in_session()
        self.__session_template.do_with_session(execute_in_session)


text:
.default .plan {
	font-family: 'Open Sans', sans-serif;
	position: relative;
}

.default .plan .title,
.default .plan .price,
.default .plan .label,
.default .plan .button {
	border-bottom: none !important;
}

.default .plan .title,
.default .plan .description {
	background-color: #3A3F41;
	color: #ecf0f1;
	font-size: 18px;
	font-weight: bold;
	padding: 15px;
	text-align: center;
}

.default .plan .price {
	position: relative;
	font-size: 18px;
	font-weight: bold;
	background-color: #ecf0f1;
	padding: 15px;
	text-align: center;
}

.default .plan .button {
	padding: 15px;
	text-align: center;
}

.default .plan .button .btn {
	background-color: #3A3F41;
	font-weight: bold;
	color: #ecf0f1;
}

.default .plan ul li {
	color: #77939a;
	background-color: #ffffff;
	padding: 10px;
	border-bottom: 1px solid #ecf0f1;
}

redpajama_set_name: RedPajamaGithub


text:
package gnu.kawa.models;

import gnu.kawa.io.CharArrayOutPort;
import gnu.kawa.io.Path;
import gnu.lists.Consumer;
import gnu.mapping.Symbol;
import gnu.xml.NamespaceBinding;
import gnu.xml.XMLPrinter;
import gnu.xml.XName;
import java.awt.*;
import java.awt.geom.*;
import java.io.ByteArrayOutputStream;

public class PictureToSvg extends PictureVisitor {
    Consumer out;
    Paint paint = StandardColor.black;
    Stroke stroke;
    int strokePropertiesSet;

    public static final String SVG_NAMESPACE_URI =
        "http://www.w3.org/2000/svg";
    public static final String XLINK_NAMESPACE_URI =
        "http://www.w3.org/1999/xlink";

    public PictureToSvg(Consumer out) {
        this.out = out;
    }

    public static Symbol svgTag(String name) {
        return Symbol.make(SVG_NAMESPACE_URI, name, "");
    }
    public static Symbol xlinkTag(String name) {
        return Symbol.make(XLINK_NAMESPACE_URI, name, "xlink");
    }
    public static void writeAttribute(String name, String value, Consumer out) {
        out.startAttribute(Symbol.valueOf(name));
        out.write(value);
        out.endAttribute();
    }
    public static void writeAttribute(String name, double value, Consumer out) {
        writeAttribute(name, formatDouble(value), out);
    }
    public static String formatDouble(double value) {
        String str = Double.toString(value);
        int len = str.length();
        int dot = str.indexOf('.');
        if (dot >= 0) {
            int j = len;
            while (j > dot && (j == dot+1 || str.charAt(j-1) == '0'))
                j--;
            str = str.substring(0, j);
        }
        return str;
    }
    public static String genShapeToString(Shape shape) {
        StringBuilder out = new StringBuilder();
        PathIterator it = shape.getPathIterator(null);
        double[] data = new double[6];
        while (! it.isDone()) {
            int kind = it.currentSegment(data);
            if (out.length() > 0)
                out.append(' ');
            char code = 0;
            int ncoords = 0;
            switch (kind) {
            case PathIterator.SEG_MOVETO:  code = 'M'; ncoords = 2; break;
            case PathIterator.SEG_LINETO:  code = 'L'; ncoords = 2; break;
            case PathIterator.SEG_QUADTO:  code = 'Q'; ncoords = 4; break;
            case PathIterator.SEG_CUBICTO: code = 'C'; ncoords = 6; break;
            case PathIterator.SEG_CLOSE:   code = 'Z'; ncoords = 0; break;
            }
            out.append(code);
            for (int j = 0; j < ncoords; j++) {
                if (j > 0)
                    out.append(',');
                out.append(data[j]);
            }
            it.next();
        }
        return out.toString();
    }

    public static void writeShapeStart(Shape shape, Consumer out) {
        if (shape instanceof Line2D) {
            Line2D s = (Line2D) shape;
            out.startElement(svgTag("line"));
            writeAttribute("x1", s.getX1(), out);
            writeAttribute("y1", s.getY1(), out);
            writeAttribute("x2", s.getX2(), out);
            writeAttribute("y2", s.getY2(), out);
        } else if (shape instanceof Rectangle2D) {
            Rectangle2D s = (Rectangle2D) shape;
            out.startElement(svgTag("rect"));
            writeAttribute("x", s.getX(), out);
            writeAttribute("y", s.getY(), out);
            writeAttribute("width", s.getWidth(), out);
            writeAttribute("height", s.getHeight(), out);
        } else if (shape instanceof RoundRectangle2D) {
            RoundRectangle2D s = (RoundRectangle2D) shape;
            out.startElement(svgTag("rect"));
            writeAttribute("x", s.getX(), out);
            writeAttribute("y", s.getY(), out);
            writeAttribute("width", s.getWidth(), out);
            writeAttribute("height", s.getHeight(), out);
            writeAttribute("rx",  s.getArcHeight()/2.0, out);
        } else if (shape instanceof Ellipse2D) {
            Ellipse2D s = (Ellipse2D) shape;
            double w = s.getWidth();
            double h = s.getHeight();
            boolean circle = w == h;
            out.startElement(svgTag(circle ? "circle" : "ellipse"));
            writeAttribute("cx", s.getCenterX(), out);
            writeAttribute("cy", s.getCenterY(), out);
            if (circle)
                writeAttribute("r", w/2, out);
            else {
                writeAttribute("rx", w/2, out);
                writeAttribute("ry", h/2, out);
            }
        } else {
            out.startElement(svgTag("path"));
            writeAttribute("d", genShapeToString(shape), out);
        }
    }
    public static void writeDrawSimple(Shape shape, Consumer out) {
        writeShapeStart(shape, out);
        writeAttribute("stroke", "black", out);
        writeAttribute("fill", "none", out);
        out.endElement();
    }
    public static void writeFillSimple(Shape shape, Consumer out) {
        writeShapeStart(shape, out);
        writeAttribute("stroke", "none", out);
        writeAttribute("fill", "black", out);
        out.endElement();
    }
    public static void writeSVGElementStart(Rectangle2D bounds, Consumer out) {
        NamespaceBinding namespaces =
            new NamespaceBinding(null, SVG_NAMESPACE_URI,
            new NamespaceBinding("xlink", XLINK_NAMESPACE_URI,
            NamespaceBinding.predefinedXML));
        out.startElement(new XName(svgTag("svg"), namespaces));
        writeAttribute("version", "1.2", out);
        double x = bounds.getX();
        double y = bounds.getY();
        double w = bounds.getWidth();
        double h = bounds.getHeight();
        writeAttribute("width", w+"px", out);
        writeAttribute("height", h+"px", out);
        writeAttribute("viewBox", x+" "+y+" "+w+" "+h, out);
    }

    private void writePaint(Paint p, boolean filling) {
        if (p instanceof Color) {
            String cname;
            if (p instanceof StandardColor)
                cname = ((StandardColor) p).getName().replace("-", "");
            else {
                Color color = (Color) p;
                int r = color.getRed();
                int g = color.getGreen();
                int b = color.getBlue();
                int alpha = color.getAlpha();
                //cname = "#%2x%2x%2x".format(r, g, b);
                cname = "#"
                    + Character.forDigit(r>>4,16) + Character.forDigit(r&15,16)
                    + Character.forDigit(g>>4,16) + Character.forDigit(g&15,16)
                    + Character.forDigit(b>>4,16) + Character.forDigit(b&15,16);
                if (alpha < 255) {
                    writeAttribute(filling ? "fill-opacity" : "stroke-opacity",
                                   alpha / 255.0, out);
                }
            }
            writeAttribute(filling ? "fill" : "stroke", cname, out);
        } else {
            // FIXME handle other types of Paint
            writeAttribute(filling ? "fill" : "stroke", "black", out);
        }
        writeAttribute(filling ? "stroke" : "fill", "none", out);
    }

    private void writeStroke(Stroke stroke, int propertiesSet) {
        if (stroke instanceof BasicStroke) {
            BasicStroke bstroke = (BasicStroke) stroke;
            if ((propertiesSet & WithPaint.STROKE_WIDTH_SET) != 0)
                writeAttribute("stroke-width", bstroke.getLineWidth(), out);
            if ((propertiesSet & WithPaint.STROKE_LINECAP_SET) != 0) {
                String str = "error-value";
                switch (bstroke.getEndCap()) {
                case BasicStroke.CAP_BUTT: str = "butt"; break;
                case BasicStroke.CAP_ROUND: str = "round"; break;
                case BasicStroke.CAP_SQUARE: str = "square"; break;
                }
                writeAttribute("stroke-linecap", str, out);
            }
            if ((propertiesSet & WithPaint.STROKE_LINEJOIN_SET) != 0) {
                String str = "error-value";
                switch (bstroke.getLineJoin()) {
                case BasicStroke.JOIN_MITER: str = "miter"; break;
                case BasicStroke.JOIN_ROUND: str = "round"; break;
                case BasicStroke.JOIN_BEVEL: str = "bevel"; break;
                }
                writeAttribute("stroke-linejoin", str, out);
            }
            if ((propertiesSet & WithPaint.STROKE_MITERLIMIT_SET) != 0)
                writeAttribute("stroke-miterlimit",  bstroke.getMiterLimit(), out);
        }
    }

    @Override
    public void visitFillShape(FillShape pic) {
        if (paint == StandardColor.transparent)
            return;
        writeShapeStart(pic.shape, out);
        writePaint(paint, true);
        out.endElement();
    }
    @Override
    public void visitDrawShape(DrawShape pic) {
        if (paint == StandardColor.transparent)
            return;
        writeShapeStart(pic.shape, out);
        writePaint(paint, false);
        writeStroke(stroke, strokePropertiesSet);
        out.endElement();
    }
    @Override
    public void visitWithPaint(WithPaint pic) {
        Paint savePaint = this.paint;
        Stroke saveStroke = this.stroke;
        int savePropertiesSet = strokePropertiesSet;
        if (pic.paint != null)
            this.paint = pic.paint;
        Stroke nstroke = pic.stroke;
        if (nstroke != null) {
            strokePropertiesSet |= pic.propertiesSet;
            if (saveStroke instanceof BasicStroke
                && nstroke instanceof BasicStroke
                && (pic.propertiesSet & WithPaint.STROKE_ALL_SET) != WithPaint.STROKE_ALL_SET)
                nstroke = WithPaint.merge((BasicStroke) nstroke, pic.propertiesSet,
                                          (BasicStroke) saveStroke);
            this.stroke = nstroke;
        }
        super.visitWithPaint(pic);
        this.paint = savePaint;
        this.stroke = saveStroke;
        this.strokePropertiesSet = savePropertiesSet;
    }
    @Override
    public void visitDrawImage(DrawImage image) {
        out.startElement(svgTag("image"));
        writeAttribute("width", image.getWidth(), out);
        writeAttribute("height", image.getHeight(), out);
        Path src = image.src;
        String srcstr = src == null ? null : src.toString();
        if (src != null && Path.uriSchemeSpecified(srcstr)) {
            out.startAttribute(xlinkTag("href"));
            out.write(srcstr);
            out.endAttribute();
        } else {
            try {
                ByteArrayOutputStream bout = new ByteArrayOutputStream();
                javax.imageio.ImageIO.write(image, "png", bout);
                byte[] imgbytes = bout.toByteArray();
                /* #ifdef JAVA8 */
                // String b64 = java.util.Base64.getEncoder()
                //     .withoutPadding().encodeToString(imgbytes);
                /* #else */
                String b64 = javax.xml.bind.DatatypeConverter
                    .printBase64Binary(imgbytes);
                /* #endif */
                out.startAttribute(xlinkTag("href"));
                out.write("data:image/png;base64,");
                out.write(b64);
                out.endAttribute();
            } catch (Throwable ex) {
                // ???
            }
        }
        out.endElement();
    }
    public void visitPBox(PBox pic) {
        int n = pic.children.length;
        AffineTransform tr = n <= 1 || pic.axis == 'Z' ? null
            : new AffineTransform();
        for (int i = 0; i < n; i++) {
            Picture child = pic.children[i];
            double offset = pic.translations[i];
            if (i > 0 && pic.axis != 'Z') {
                if (pic.axis == 'X')
                    tr.setToTranslation(offset, 0);
                else
                    tr.setToTranslation(0, offset);
                visitWithTransform(child, tr);
            }
            else
                child.visit(this);
        }
    }

    public static String transformAttribute(AffineTransform tr) {
        double m00 = tr.getScaleX();
        double m10 = tr.getShearY();
        double m01 = tr.getShearX();
        double m11 = tr.getScaleY();
        double m02 = tr.getTranslateX();
        double m12 = tr.getTranslateY();
        return String.format("matrix(%g %g %g %g %g %g)",
                             m00, m10, m01, m11, m02, m12);
    }
    @Override
    public void visitWithTransform(WithTransform pic) {
        visitWithTransform(pic.picture, pic.transform);
    }
    public void visitWithTransform(Picture pic, AffineTransform tr) {
        out.startElement(svgTag("g"));
        writeAttribute("transform", transformAttribute(tr), out);
        pic.visit(this);
        out.endElement();
    }
    void writeCompOp(Composite comp) {
        String op = null;
        if (comp == AlphaComposite.Clear)
            op = "clear";
        else if (comp == AlphaComposite.DstOver)
            op = "dst-over";
        else if (comp == AlphaComposite.Src)
            op = "src";
        else if (comp == AlphaComposite.SrcOver)
            op = "src-over";

        if (op != null)
            writeAttribute("comp-op", op, out);
    }

    @Override
    public void visitWithComposite(WithComposite pic) {
        out.startElement(svgTag("g"));
        Composite op = pic.singleOp();
        int n = pic.children.length;
        if (n == 0) {
        } else if (op != null) { // simple case
            writeCompOp(op);
            for (int i = 0;  i < n;  i++) {
                pic.children[i].visit(this);
            }
        } else {
            Composite prev = null;
            for (int i = 0;  i < n;  i++) {
                op = pic.composite[i];
                if (op != null && op != prev) {
                    if (prev != null)
                        out.endElement();
                    out.startElement(svgTag("g"));
                    writeCompOp(op);
                    prev = op;
                }
                pic.children[i]. visit(this);
            }
            if (prev != null)
                out.endElement();
        }
        out.endElement();
    }
}


text:
STOKE
=====

STOKE is a stochastic optimizer for the x86-64 instruction set. STOKE uses
random search to explore the extremely high-dimensional space of all possible
program transformations. Although any one random transformation is unlikely to
produce a code sequence that is both correct and an improvement over the
original, the repeated application of millions of transformations is sufficient
to produce novel and non-obvious code sequences that have been shown to
outperform the code produced by general-purpose and domain-specific compilers,
and in some cases expert hand-written code.

STOKE has appeared in a number of publications. For a thorough introduction to
the design of STOKE, see:

- [**Stochastic Superoptimization** -- ASPLOS 2013](https://raw.githubusercontent.com/StanfordPL/stoke/develop/docs/papers/asplos13.pdf)
- [**Data-Driven Equivalence Checking** -- OOPSLA 2013](https://raw.githubusercontent.com/StanfordPL/stoke/develop/docs/papers/oopsla13b.pdf)
- [**Stochastic Optimization of Floating-Point Programs with Tunable Precision** -- PLDI 2014](https://raw.githubusercontent.com/StanfordPL/stoke/develop/docs/papers/pldi14a.pdf)
- [**Conditionally Correct Superoptimization** -- OOPSLA 2015](https://raw.githubusercontent.com/StanfordPL/stoke/develop/docs/papers/oopsla15a.pdf)
- [**Stratified Synthesis: Automatically Learning the x86-64 Instruction Set** -- PLDI 2016](https://raw.githubusercontent.com/StanfordPL/stoke/develop/docs/papers/pldi16.pdf)

Table of Contents
=====
0. [Prerequisites](#prerequisites)
1. [Choosing a STOKE version](#choosing-a-stoke-version)
2. [Building STOKE](#building-stoke)
 1. [Using the formal validator](#using-the-formal-validator)
3. [Using STOKE](#using-stoke)
4. [Additional Features](#additional-features)
5. [Extending STOKE](#extending-stoke)
 1. [Code Organization](#code-organization)
 2. [Gadgets](#gadgets)
 3. [Initial Search State](#initial-search-state)
 4. [Search Transformations](#search-transformations)
 5. [Cost Function](#cost-function)
 6. [Live-out Error](#live-out-error)
 7. [Verification Strategy](#verification-strategy)
 8. [Command Line Args](#command-line-args)
6. [FAQ](#faq)
7. [Contact](#contact)

Prerequisites
=====

STOKE will run on modern 64-bit x86 processors.  We officially support Haswell
processors with AVX2 extensions.  STOKE should also run on Sandy Bridge
systems (with AVX, but not AVX2).  It might run on newer architectures, but we currently don't test these.
Running `./configure.sh` as described next will automatically configure the build for the correct architecture.

STOKE is supported on the latest Ubuntu LTS release; in practice, it will also
run on Ubuntu 13.10+ and on debian testing.  If you're trying to get STOKE to
work on another linux distribution, having the right version of g++ is key.
STOKE is supported on 4.9 only.
It should also work on later versions, but it will not work with g++ 4.8.x (missing regular expression support), and  g++ 4.7.x and older
definitely will not work.

Most of STOKE's software dependencies are available through apt. These can be
satisfied by typing:

    $ sudo apt-get install bison ccache cmake doxygen exuberant-ctags flex g++-4.9 g++-multilib gcc-4.9 ghc git libantlr3c-dev libboost-dev libboost-filesystem-dev libboost-thread-dev libcln-dev libghc-regex-compat-dev libghc-regex-tdfa-dev libghc-split-dev libjsoncpp-dev python subversion libiml-dev libgmp-dev

Note that your distribution might not have g++-4.9 by default.  You may consider installing a PPA as described here: https://askubuntu.com/questions/466651/how-do-i-use-the-latest-gcc-4-9-on-ubuntu-14-04

The rest of the dependencies will be fetched automatically as part of the build
process.

Downloading STOKE
=====

The entire STOKE code base is available on GitHub under the Apache Software
License version 2.0 at [github.com/StanfordPL/stoke](https://github.com/StanfordPL/stoke/).

To check it out, type:

    $ git clone https://github.com/StanfordPL/stoke

This will check out the default `develop` branch.  Unless you are looking for a specific version or modification of STOKE, this is the branch to use.  It contains all the latest changes and is reasonably stable.  This branch is supposed to always pass all tests.

Building STOKE
=====

See the previous sections on how to download STOKE, a list of dependencies, and to check your hardware
support level.  The remainder of STOKE's software dependencies are available on
GitHub and will be downloaded automatically the first time that STOKE is built.  When you build STOKE the first time, run

    $ ./configure.sh

This will figure out the correct build parameters (such as the platform).  To build STOKE, run

    $ make

To add STOKE and its related components to your path, type:

    $ export PATH=$PATH:/<path_to_stoke>/bin

To run the tests, choose the appropriate command:

    $ make test

The files generated during the build process can be deleted by typing:

    $ make clean

To delete STOKE's dependencies as well (this is useful if an error occurs during the first build), type:

    $ make dist_clean

Using STOKE
=====

The following toy example shows a typical workflow for using STOKE. All of the
following code can be found in the `examples/tutorial/` directory.  As this
code is tested using our continuous integration system, the code there will
always be up-to-date, but this README can fall behind.

Consider a
C++ program that repeatedly counts the number of bits (population count) in the
64-bit representation of an integer. (Keeping track of a running sum prevents
`g++` from eliminating the calls to `popcnt()` altogether.)

```c++
// main.cc

#include <cstdlib>
#include <stddef.h>
#include <stdint.h>

using namespace std;

size_t popcnt(uint64_t x) {
  int res = 0;
  for ( ; x > 0; x >>= 1 ) {
    res += x & 0x1ull;
  }
  return res;
}

int main(int argc, char** argv) {
  const auto itr = atoi(argv[1]);

  auto ret = 0;
  for ( auto i = 0; i < itr; ++i ) {
    ret += popcnt(i);
  }

  return ret;
```

STOKE is a compiler and programming language agnostic optimization tool. It can
be applied to any x86-64 ELF binary. Although this example uses the GNU
toolchain, nothing prevents the use of other tools. To build this code with
full optimizations, type:

    $ g++ -std=c++11 -O3 -fno-inline main.cc

To measure runtime, type:

    $ time ./a.out 100000000

    real  0m1.046s
    user  0m1.047s
    sys   0m0.000s

A profiler will reveal that the runtime of `./a.out` is dominated by calls to
the `popcnt()` function. STOKE can be used to improve the implementation of
this function as follows. The first step is to disassemble the program by
typing:

    $ stoke extract -i ./a.out -o bins

This will produce a directory named `bins` that contains the text of every
function contained in the binary `./a.out`.

Help for stoke or any of its subcommands can be obtained by typing:

    $ stoke -h
    $ stoke <subcommand> -h

STOKE can accept arguments either through the command line or through a
configuration file. The invocation of `stoke extract` shown above is equivalent
to the following:

    $ stoke extract --config extract.conf

Where `extract.conf` contains:

```
##### stoke extract config file

-i ./a.out # Path to the elf binary to disassemble
-o bins # Path to the directory to store disassembled text in
```

Every STOKE subcommand can be used to generate example configuration files by
typing:

    $ stoke <subcommand> --example_config <path/to/file.conf>

Because `main.cc` was compiled using `g++`, the text of the `popcnt()` function
will appear under the mangled name `_Z6popcntm` in `bins/_Z6popcntm.s`.

```asm
  .text
  .globl _Z6popcntm
  .type _Z6popcntm, @function
_Z6popcntm:
  xorl   %eax,%eax
  testq  %rdi,%rdi
  je     .L_4005b0
  nop
.L_4005a0:
  movq   %rdi,%rdx
  andl   $0x1,%edx
  addq   %rdx,%rax
  shrq   $0x1,%rdi
  jne    .L_4005a0
  retq
.L_4005b0:
  retq
  nop
  nop
  .size _Z6popcntm, .-_Z6popcntm
```

The next step is to generate a set of testcases for guiding STOKE's search
procedure. These can be obtained by typing:

    $ stoke testcase --config testcase.conf

where `testcase.conf` contains:

```
##### stoke testcase config file

--bin ./a.out # The name of the binary to use to generate testcases
--args 10000000 # Command line arguments that should be passed to ./a.out
--functions bins # Disassembly directory created by stoke extract

-o popcnt.tc # Path to file to write testcases to

--fxn _Z6popcntm # The name of the function to generate testcases for
--max_testcases 1024 # The maximum number of testcases to generate.
```

The resulting file will contain 1024 entires, all of the form:

```
Testcase 0:

%rax     00 00 00 00 00 98 96 80
%rcx     00 00 00 00 00 00 00 00
%rdx     00 00 00 00 00 00 00 0a
%rbx     00 00 00 00 00 00 00 01
%rsp     00 00 7f ff 97 44 36 28
%rbp     00 00 00 00 00 00 00 00
%rsi     19 99 99 99 99 99 99 99
%rdi     00 00 00 00 00 00 00 00
%r8      00 00 2a c9 68 1a 50 40
%r9      00 00 7f ff 97 44 46 01
%r10     00 00 00 00 00 98 96 80
%r11     00 00 00 00 00 00 00 0a
%r12     00 00 00 00 00 98 96 80
%r13     00 00 7f ff 97 44 37 20
%r14     00 00 00 00 00 00 00 00
%r15     00 00 00 00 00 00 00 00

%ymm0    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00
%ymm1    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f
%ymm2    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm3    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00 ff
%ymm4    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm5    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm6    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm7    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm8    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm9    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm10   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm11   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm12   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm13   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm14   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
%ymm15   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

%cf      0
%1       1
%pf      1
%0       0
%af      0
%0       0
%zf      0
%sf      0
%tf      0
%if      1
%df      0
%of      0
%iopl[0] 0
%iopl[1] 0
%nt      0
%0       0
%rf      0
%vm      0
%ac      0
%vif     0
%vip     0
%id      0

[ 00007fff 97443630 - 00007fff 97443620 ]
[ 1 valid rows shown ]

00007fff 97443628   d d d d d d d d   00 00 00 00 00 40 04 6c

[ 00000000 00000000 - 00000000 00000000 ]
[ 0 valid rows shown ]

[ 00000000 00000000 - 00000000 00000000 ]
[ 0 valid rows shown ]

0 more segment(s)
```

Each entry corresponds to the hardware state that was observed just prior to an
execution of the `popcnt()` function. The first 60 rows represent the contents
of general purpose, sse, and eflags registers, and the remaining rows represent
the contents of memory, both on the stack and the heap. Memory is shown eight
bytes at a time, where a block of eight bytes appears only if the target
dereferenced at least one of those bytes. Each row contains values and state
flags. Bytes are flagged as either (v)alid (the target dereferenced this byte),
  or (.)invalid (the target did not dereference this byte).

Each of the random transformations performed by STOKE are evaluated with
respect to the contents of this file. Rewrites are compiled into a sandbox and
executed beginning from the machine state represented by each entry. Rewrites
are only permitted to dereference defined locations. This includes registers
that are flagged as `def_in` (see `synthesize.conf`, below), memory locations that
are flagged as 'v', or locations that were written previously. Rewrites are
permitted to write values to all registers and to any memory location that is
flagged as valid.

STOKE will produce optimal code that works on the testcases.  The testcases
need to be selected to help ensure that STOKE doesn't produce an incorrect
rewrite.  In our main.cc file in `examples/tutorial` we choose arguments to the
`popcnt` function to make sure that it sometimes provides arguments that use
more than 32 bits.  Otherwise, STOKE will sometimes produce a rewrite using the
`popcntl` instruction, which only operates on the bottom half of the register,
instead of the `popcntq` instruction, which operates on the whole thing.
  Alternatively you can use the formal validator in bounded mode with a large
  bound (over 32).  This large bound is tractable because this example doesn't
  has a small number of cases for memory aliasing (namely, none at all!).  If a
  counterexample is found it can be automatically added to the search so STOKE
  won't make this mistake again.

The STOKE sandbox will safely halt the execution of rewrites that perform
undefined behavior. This includes leaving registers in a state that violates
the x86-64 callee-save ABI, dereferencing invalid memory, performing a
computation that results in a floating-point exception, or becoming trapped in
a loop that performs more than `max_jumps` (see `synthesize.conf`, below).

The final step is to use these testcases and the target code contained in
`bins/_Z6popcntm.s` to run STOKE search in synthesis mode (i.e., trying to find a program starting from the empty program) by typing:

    $ stoke synthesize --config synthesize.conf

where `synthesize.conf` contains:

```
##### stoke search config file

--out result.s # Path to write results to

--target bins/_Z6popcntm.s # Path to the function to optimize

--def_in "{ %rax %rdi }" # The registers that are defined on entry to the target
--live_out "{ %rax }" # The registers that are live on exit from the target

--testcases popcnt.tc # Path to testcase file
--training_set "{ 0 ... 7 }" # Testcases to use for measuring correctness during search
--test_set "{ 8 ... 1023 }"  # Testcases to use as holdout set for checking correctness

--distance hamming # Metric for measuring error between live-outs
--misalign_penalty 1 # Penalty for results that appear in the wrong location
--reduction sum # Method for summing errors across testcases
--sig_penalty 9999 # Score to assign to rewrites that produce non-zero signals

--cost "correctness + latency" # Measure performance by summing instruction latencies

--global_swap_mass 0 # Proposal mass
--instruction_mass 1 # Proposal mass
--local_swap_mass 1 # Proposal mass
--opcode_mass 1 # Proposal mass
--operand_mass 1 # Proposal mass
--rotate_mass 0 # Proposal mass

--beta 1 # Search annealing constant
--initial_instruction_number 5 # The number of nops to start with

--statistics_interval 100000 # Print statistics every 100k proposals
--timeout_iterations 16000000 # Propose 16m modifications total before giving up
--cycle_timeout 1000000 # Try 1m modifications before restarting

--strategy hold_out # Verify results using a larger hold out testcase set
```

STOKE search will produce two types of status messages. Progress update
messages will be printed whenever STOKE discovers a new lowest cost verified or
unverified rewrite. The code shown on the left is not equivalent to the target
code; the code shown on the right is with respect to the current set of
testcases.

```
Progress Update:

Lowest Cost Discovered (9)         Lowest Known Correct Cost (15)

btrq $0xffffffffffffffc0, %rdi     testq %rdi, %rdi
retq                               je .L_X64ASM_0
                                   xorl %eax, %eax
                                   .L_X64ASM_1:
                                   movl %edi, %edx
                                   andl $0x1, %edx
                                   addl %edx, %eax
                                   shrq $0x1, %rdi
                                   jne .L_X64ASM_1
                                   cltq
                                   retq
                                   .L_X64ASM_0:
                                   xorl %eax, %eax
                                   retq
```

Statistics updates will be printed every `statistics_interval` proposals.
Statistics are shown for the number of proposals that have taken place, elapsed
time, proposal throughput, and for each of the transformations specified to
have non-zero mass in `synthesize.conf`.

```
Statistics Update:

Iterations:   100000
Elapsed Time: 0.0836948s
Iterations/s: 1.19482e+06

Move Type       Proposed     Succeeded     Accepted

Instruction     16.791%      5.83%         2.009%
Opcode          16.646%      8.857%        4.013%
Operand         16.593%      10.444%       6.864%
Rotate          16.611%      0.791%        0.789%
Local Swap      16.597%      1.556%        1.128%
Global Swap     16.762%      7.066%        6.08%
Extension       0%           0%            0%

Total           100%         34.544%       20.883%
```

When search has run to completion, STOKE will write the lowest cost verified
rewrite that it discovered to `result.s`. Because this is a particularly simple
example, STOKE is almost guaranteed to produce the optimal rewrite:

```asm
  .text
  .globl _Z6popcntm
  .type _Z6popcntm @function
_Z6popcntm:
  popcnt %rdi, %rax
  retq
  .size _Z6popcntm, .-_Z6popcntm
```

This result can then be patched back into the original binary by typing:

    $ stoke replace --config replace.conf

where `result.conf` contains:

```
##### stoke replace config file

-i ./a.out # Path to the elf binary to patch
--rewrite result.s # Path to the replacement function
```

And runtime can once again be measured by typing:

    $ time ./a.out 100000000

    real  0m0.133s
    user  0m0.109s
    sys   0m0.000s

As expected, the results are close to an order of magnitude faster than the original.

Using the Formal Validator
-----

STOKE includes a formal validator.  It's design and interface
are detailed in the `src/validator/README.md` file.  To use the formal
validator instead of hold out testing, specify `--strategy bounded` for any
STOKE binary that you use.  For code with loops, all paths will be explored up
to a certain depth, specified using the --bound argument, which defaults to 2.  There's also `--strategy ddec` which attempts to run the data-driven equivalence checking algorithm; however, the current implementation isn't very robust -- please file bug reports with (target, rewrite) pairs that fail to validate but should.

An example of using the validator can be found in the `examples/pairity`
folder; this example has a Makefile much like the tutorial's and should be easy
to follow.  The key difference is that the pairity example does not use
testcases to guide search.  Instead, after producing a candidate rewrite,
the validator checks for equivalence.  If the codes are not equivalent,
a counterexample is found, and this is used as a new testcase to help guide search.

There are some important limitations to keep in mind while using the validator:

- Only some instructions are supported.  The `--validator_must_support` flag
can be used to only propose instructions that can be validated.
- Only the general purpose registers, SSE registers (`ymm0`-`ymm15`) and five of
the status flags (`CF`, `SF`, `PF`, `ZF`, `OF`) are supported.
- Memory is now fully supported, even in the presence of complex aliasing.

Additional Features
=====

In addition to the subcommands described above, STOKE has facilities for
debugging and benchmarking the performance of each of its core components:

- `stoke debug cfg`: Generate a pdf of a control flow graph.
- `stoke debug cost`: Compute the cost of a rewrite.
- `stoke debug sandbox`: Step through the execution of a rewrite.
- `stoke debug search`: View the changes produced by performing and undoing a program transformation.
- `stoke debug state`: Check the behavior of operators that manipulate hardware machine states.
- `stoke debug verify`: Check the equivalence of two programs.
- `stoke benchmark cfg`: Measure the time required to recompute a control flow graph.
- `stoke benchmark cost`: Measure the time required to compute a cost function.
- `stoke benchmark sandbox`: Measure the time required to execute a program in a STOKE sandbox.
- `stoke benchmark search`: Measure the time required to perform and undo a transformation to a program.
- `stoke benchmark state`: Measure the time required to reset the memory of a hardware machine state.
- `stoke benchmark verify`: Measure the time required to check the equivalence of two programs.

Shell completion
-----

STOKE also comes with support for bash and zsh completion.  To enable either, type:

  $ make bash_completion
  $ make zsh_completion

Using functions to be proposed by STOKE
-----
STOKE can not only propose instructions when searching for programs, but also propose calls to a list of known functions using the `--functions` command-line argument.  To decide whether these functions read any undefined state (before proposing them), we use a dataflow analysis.  Sometimes, the dataflow analysis can be too imprecise, which is why STOKE allows the user to annotate dataflow information in comments.  Here is an example of a function that clears the overflow flag.  STOKEs dataflow analysis is too imprecise for this code.

      .text
      .globl clear_of
      .type clear_of, @function
    #! maybe-read { }
    #! maybe-write { %of %r15 }
    #! maybe-undef { }
    .clear_of:
      pushfq
      popq %r15
      andq $0xfffff7ff, %r15
      pushq %r15
      popfq
      retq

    .size clear_of, .-clear_of

Note that it is enough to specify the maybe sets, as STOKE will automatically realize that the must sets need to be contained in the maybe set.

Extending STOKE
=====

This repository contains a minimal implementation of STOKE as described in
the academic papers about STOKE. Most, but not all of the features
described in those papers appear here. Developers who
are interested in refining these features or adding their own extensions are
encouraged to try modifying this implementation as described below.

Code Organization
-----

The STOKE source is organized into modules, each of which correspond to a
subdirectory of the `src/` directory:

- `src/analysis`: An aliasing analysis used by the validator.
- `src/cfg`: Control flow graph representation and program analysis.
- `src/cost`: Different cost functions that can be used in the search.
- `src/disassembler`: Runs objdump and parses the results into STOKE's format.
- `src/expr`:  A helper used to parse arithmetic expressions in config files.
- `src/ext`: External dependencies.
- `src/sandbox`: A sandbox for testing proposed code on the hardware.
- `src/search`: An implementation of an MCMC-like algorithm for search.
- `src/state`: Data structures to represent concrete machine states (testcases).
- `src/stategen`: Generates concrete machine states (testcaes) for a piece of code.
- `src/symstate`: Models the symbolic state of the hardware; only used by the formal validator.
- `src/target`: Code to find which instruction sets the CPU supports.
- `src/transform`: Transforms used during search to mutate the code.
- `src/tunit`: Classes for representing a function (x86-64 code along with a name and other metadata).
- `src/verifier`: Wrappers around verification techniques such as testing for formal validation.
- `src/validator`: The formal validator for proving two codes equivalent.

The `tools/` directory has the code that performs application logic and reads
command line arguments.

- `tools/apps`: The application logic for stoke binaries
- `tools/args`: Lists of command line arguments used by a gadget (see below).
- `tools/gadgets`: Modules used by applications to configure internal APIs with command line arguments.
- `tools/io`: Code to read/write certain kinds of command line arguments.
- `tools/scripts`: Where we put stuff when we don't have a better place.  Nothing to see here.
- `tools/target`: Arbitrarily named directory with code to read CPU features from cpuinfo.

Gadgets
-----

The stoke codebase is setup in a very modular way.  We have components like the
`Sandbox`, which emulates execution of a rewrite on hardware.  Or, we have
subclasses of `CostFunction` which evaluate the quality of a rewrite.  Or, we
have an `SMTSolver` which is used by the formal validator to query a backend
like Z3 or CVC4.

Often, several stoke applications will wish to configure one of these modules
in the same way, depending on command line arguments.  Thus, we have "Gadgets".
A "Gadget" is a subclass of the class you wish to configure which takes care of
extracting all the appropriate command line arguments.  Some Gadgets, like
`SandboxGadget` just define a constructor so that modifies the object's
configuration.  More involved ones, like `CostFunctionGadget` actually do work
to create a new `CostFunction` object and define methods that act as a wrapper.

Therefore, if you want to add a command line option to an existing component of
stoke, you normally are going to want to modify the gadget for that component
in `tools/gadgets` and add the argument in `tools/args`.  Once you do that, it
should show up uniformly in all of the stoke tools that use that module.

Initial Search State
-----

Initial state types are defined in `src/search/init.h` along with an additional
type for user-defined extensions.

```c++
enum class Init {
  EMPTY,
  ZERO,
  TARGET,
  PREVIOUS,

  // Add user-defined extensions here ...
  EXTENSION
};
```

Initial state is specified using the `--init` command line argument which controls the initial values
given to the current, lowest cost, and lowest cost correct search states. This value
affects the behavior of the `Search::configure() const` method, which
dispatches to the family of `Search::configure_xxxxx() const` methods. User-defined
extensions should be placed in the `Search::configure_extension() const` method,
which can be triggered by specifying `--init extension`.

```c++
void Search::configure_extension(const Cfg& target, SearchState& state) const {
  // Add user-defined logic here ...

  // Invariant 1: Search state should agree with target on boundary conditions.
  assert(state.current.def_ins() == target.def_ins());
  assert(state.current.live_outs() == target.live_outs());

  assert(state.best_yet.def_ins() == target.def_ins());
  assert(state.best_yet.live_outs() == target.live_outs());

  assert(state.best_correct.def_ins() == target.def_ins());
  assert(state.best_correct.live_outs() == target.live_outs());

  // Invariant 2: Search state must be in a valid state. This function isn't on
  // a critical path, so this can safely be accomplished by calling
  state.current.recompute();
  state.best_yet.recompute();
  state.best_correct.recompute();

  // Invariant 3: Search state must agree on first instruction. This instruction
  // must be the label definition that appears in the target.
  assert(state.current.get_code()[0] == target.get_code()[0]);
  assert(state.best_yet.get_code()[0] == target.get_code()[0]);
  assert(state.best_correct.get_code()[0] == target.get_code()[0]);

  // See Search::configure for additional invariants
}
```

Search Transformations
-----

Transformation types are defined in the `src/transform` directory.  Each
transform is a subclass of the abstract class `Transform`.  Existing transforms are,

| Name | Description |
| ---- | ----------- |
| add_nops | Adds one extra nop instruction into the rewrite. |
| delete | Deletes one instruction at random. |
| instruction | Replaces an instruction with another one chosen at random. |
| opcode | Replaces an instruction's opcode with a new one that takes operands of the same type. |
| operand | Replaces an operand of one instruction with another. |
| rotate | Formerly "resize".  Moves an instruction from one basic block to another, and shifts all the instructions in between. |
| local_swap | Takes two instructions in the same basic block and swaps them. |
| global_swap |  Takes two instructions in the entire program and swaps them. |
| weighted | Selects from among several other transforms at random. |

These subclasses each implement `operator()(Cfg& cfg)` to mutate a Cfg.  This
function returns an object, `TransformInfo` that contains all the information
needed to undo this transformation, and also whether the transform succeeded
(transforms are allowed to fail).  It's common for this object to be set with
indexes of instructions in the code that were modified, for example.  The
subclass also implements `undo(Cfg& cfg, TransformInfo ti)`.

Transforms will often want to select from a collection of operands and opcodes,
and for this purpose they can access the `pools_` protected variable of the
Transform` superclass.  This is of type `TransformPools` and allows access to
these collections.  This makes it possible to configure the collection of
available opcodes and operands independently of the transforms.  Also, the
`Transform` superclass has a `gen_` member which is used to produce random
numbers with a known seed.

Transformation weights are specified using the family of `--xxxxx_mass` command
line arguments. These values control the distribution of proposals that are
made by the WeightedTransform, which is the transform used by the
search.

A simple example of how to impelement a transform is in
`src/transform/global_swap.cc`.  Note that all transforms must appropriately
make a call to recompute any `Cfg` information that needs to be updated and
ensure that `cfg.check_invariants()` returns true when done (you can assume it
    returns true at the beginning of the function).

Cost Function
-----

A cost function is specified using the `--cost` command line argument.  It's an
expression composed using standard unsigned arithmetic operators.  As
variables, you can use several measurements of the current rewrite.  The most
important of these is `correctness`.  The value `correctness` is (by default)
the number of bits that differ in the outputs of the target versus the rewrite
summed across all testcases.  There are some tunable options for this, for
example, for floating point computations.  In all cases, lower cost is better.

Some other important cost-variables you can use are:

| Name | Description |
| ---- | ----------- |
| binsize | The size (in bytes) of the assembled rewrite using the x64asm library. |
| correctness | How "correct" the rewrite's output appears.  Very configurable. |
| size | The number of instructions in the assembled rewrite. |
| latency | A poor-man's estimate of the rewrite latency, in clock cycles, based on the per-opcode latency table in `src/cost/tables`. |
| measured | An estimate of running time by counting the number of instructions actually executed on the testcases.  Good for loops and algorithmic improvements.  |
| sseavx |  Returns '1' if both avx and sse instructions are used (this is usually bad!), and '0' otherwise.  Often used with a multiplier like `correctness + 1000*sseavx` |
| nongoal | Returns '1' if the code (after minimization) is found to be equivalent to one in `--non_goal`.  Can also be used with a multiplier. |

In typical usage, you will combine the value of `correctness` with other values
you want to optimize for.  A good starting point is `correctness + measured` or
`correctness + latency` (the latter being default).  Improvements might assign
an SSE-AVX penalty, like `correctness + latency + 10000*sseavx`.

To add a new cost function, drop a file into `src/cost` that subclasses
`stoke::CostFunction`.  Look at `src/cost/sseavx.h` for a simple example.  It
comes down to overloading the `operator()` function to return the value you
want.  Look at `measured.h` for an example of how to use runtime data from the
sandbox to generate values.  Then, add an entry to the map in
`tools/gadgets/cost_function.h` so that your new function can be found on the
command line.

Live-out Error
-----

Live-out error measurement types are defined in `src/cost/distance.h` along with an additional type for user-defined extensions.

```c++
enum class Distance {
  HAMMING,
  ULP,

  // Add user-defined extensions here ...
  EXTENSION
};
```

Measurement type is specified using the `--distance` command line argument.
This value controls the behavior of the `CorrectnessCost::evaluate_distance()
const` method, which dispatches to the family of
`CorrectnessCost::xxxxx_distance() const` methods, each of which represent a
method computing the distance between 64-bit values. User-defined extensions
should be placed in the `CostFunction::extension_distance() const` method,
which can be triggered by specifying `--distance extension`.

```c++
Cost CostFunction::extension_distance(uint64_t x, uint64_t y) const {
  Cost res = 0;

  // Add user-defined implementation here ...

  // Invariant 1: Return value should not exceed max_error_cost
  assert(res <= max_error_cost);

  return res;
}
```

Verification Strategy
-----

The verification strategy specifies what kind of verification to do on the
rewrite.  It's controlled using the `--strategy` command line argument.  Right
now, the options are 'hold_out', 'straight_line' or 'bounded'.

Command Line Args
-----

Command line arguments can be added to any of the STOKE subcommands using the
following syntax. Argument separators which are printed as part of help
messages are specified by defining a heading variable:

```c++
auto& heading = Heading::create("Heading Description:");
```

Command line flags are specified by declaring a `FlagArg`.

```c+++
auto& flag = FlagArg::create("flag_name")
  .alternate("alternate_flag_name")
  .description("What this flag does");
```

Any of the built-in c++ primitive types are specified by declaring a `ValueArg`.

```c++
auto& val = ValueArg<int>::create("value_name")
  .alternate("alternate_value_name")
  .usage("<int>")
  .description("What this value represents")
  .default_val(0);
```

User-defined types are specified by additionally providing function objects that define I/O methods.

```c++
struct T {
  int x, y, z;
};

struct Reader {
  void operator()(istream& is, T& t) const {
    is >> t.x >> t.y >> t.z;
  }
};

struct Writer {
  void operator()(ostream& os, const T& t) const {
    os << t.x << " " << t.y << " " << t.z;
  }
};

auto& val = ValueArg<T, Reader, Writer>::create("value_name")
  .alternate("alternate_value_name")
  .usage("<int> <int> <int>")
  .description("What this value represents")
  .default_val({0,0,0});
```

For complex values that are better suited to being read from files, a `FileArg`
may be more appropriate than a `ValueArg`. The syntax is identical.

```c++
auto& val = FileArg<Complex, ComplexReader, ComplexWriter>::create("value_name")
  .alternate("alternate_value_name")
  .usage("<complex representation>")
  .description("What this value represents")
  .default_val(Complex());
```

FAQ
=====

1. What is the different between `stoke synthesize` and `stoke optimize`?
Both use the same core search algorithm, but in synthesis mode, STOKE starts from the empty program and tries to find a rewrite from scratch.  This is great for finding implementations that are very different than the target.  In optimization mode however, STOKE starts from an initial program, usually the target.  This allows STOKE to work on much longer programs (because it already starts with a correct program) and apply optimizations to that program.

Contact
=====

Questions and comments are encouraged.  Please reach us through the GitHub issue tracker, or alternatively at `stoke-developers@lists.stanford.edu`.


text:
from unittest import TestCase, main

from classes.graph import Graph, Edge, Vertex
from classes.solver import DynamicProgramming
from classes.semiring import semirings
from classes.semiring import SemiringMinPlusElement, SemiringPlusMulElement

class TestDynamicProgrammingBasicProperties(TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_constructor(self):
        v_zero = Vertex()
        v_one = Vertex()
        e = Edge(v_zero, v_one)
        g = DynamicProgramming([v_zero, v_one], [e])
        self.assertIsInstance(g, Graph)
        self.assertIsInstance(g, DynamicProgramming)

    def test_solve_incorrect_start(self):
        vertex = Vertex()
        g = DynamicProgramming([], [])
        with self.assertRaises(ValueError):
            g.set_start(vertex)

    def test_solve_incorrect_finish(self):
        vertex = Vertex()
        g = DynamicProgramming([], [])
        with self.assertRaises(ValueError):
            g.set_finish(vertex)

    def test_solve_simple(self):
        """Solve simple problem

        start --1--> finish

        Right answer is 1
        """
        start = Vertex('start')
        finish = Vertex('finish')
        for S in semirings:
            e = Edge(start, finish, S.unity())
            g = DynamicProgramming([start, finish], [e])
            g.set_start(start)
            g.set_finish(finish)
            self.assertEqual(g.solve(S), S.unity())

    def test_solve_square(self):
        """Solve problem with square

        start ---1--> A
          |           |
          1           1
          |           |
          V           V
          B ---1--> finish

        Right answer is (1*1 + 1*1)
        """

        start = Vertex('start')
        finish = Vertex('finish')
        a = Vertex('a')
        b = Vertex('b')

        for S in semirings:
            start_a = Edge(start, a, S.unity())
            start_b = Edge(start, b, S.unity())

            a_finish = Edge(a, finish, S.unity())
            b_finish = Edge(b, finish, S.unity())

            g = DynamicProgramming([start, a, b, finish], [start_a, start_b,
                                                        a_finish, b_finish])
            g.set_start(start)
            g.set_finish(finish)

            self.assertEqual(g.solve(S), S.unity()+S.unity())

    def test_solve_big_square(self):
        """Find length of the shortest path (min,+)

        start -5-> A ---1----> B --3--> C
          |                             |
          1                             9
          |                             |
          V                             V
          x --5--> y --2--> z --1--> finish

        Right answer is 9
        """

        start = Vertex('start')
        finish = Vertex('finish')

        a = Vertex('a')
        b = Vertex('b')
        c = Vertex('c')

        x = Vertex('x')
        y = Vertex('y')
        z = Vertex('z')

        start_a = Edge(start, a, SemiringMinPlusElement(5))
        a_b = Edge(a, b, SemiringMinPlusElement(1))
        b_c = Edge(b, c, SemiringMinPlusElement(3))
        c_finish = Edge(c, finish, SemiringMinPlusElement(9))

        start_x = Edge(start, x, SemiringMinPlusElement(1))
        x_y = Edge(x, y, SemiringMinPlusElement(5))
        y_z = Edge(y, z, SemiringMinPlusElement(2))
        z_finish = Edge(z, finish, SemiringMinPlusElement(1))

        g = DynamicProgramming([start, finish, a, b, c, x, y, z],
                               [start_a, a_b, b_c, c_finish,
                                start_x, x_y, y_z, z_finish])
        g.set_start(start)
        g.set_finish(finish)

        self.assertEqual(g.solve(SemiringMinPlusElement),
                         SemiringMinPlusElement(9))

    def test_solve_crossed_square(self):
        """Find length of the shortest path (min,+)

        start -5-> A ---1----> B --3--> C
          |        |                    |
          1        0                    9
          |        |                    |
          V        V                    V
          x --5--> y --2--> z --1--> finish

        Right answer is 8
        """

        start = Vertex('start')
        finish = Vertex('finish')

        a = Vertex('a')
        b = Vertex('b')
        c = Vertex('c')

        x = Vertex('x')
        y = Vertex('y')
        z = Vertex('z')

        start_a = Edge(start, a, SemiringMinPlusElement(5))
        a_b = Edge(a, b, SemiringMinPlusElement(1))
        b_c = Edge(b, c, SemiringMinPlusElement(3))
        c_finish = Edge(c, finish, SemiringMinPlusElement(9))

        start_x = Edge(start, x, SemiringMinPlusElement(1))
        x_y = Edge(x, y, SemiringMinPlusElement(5))
        y_z = Edge(y, z, SemiringMinPlusElement(2))
        z_finish = Edge(z, finish, SemiringMinPlusElement(1))

        a_y = Edge(a, y, SemiringMinPlusElement(0))

        g = DynamicProgramming([start, finish, a, b, c, x, y, z],
                               [start_a, a_b, b_c, c_finish,
                                start_x, x_y, y_z, z_finish,
                                a_y])
        g.set_start(start)
        g.set_finish(finish)

        self.assertEqual(g.solve(SemiringMinPlusElement),
                         SemiringMinPlusElement(8))

if __name__ == '__main__':
    main()


text:
#include "test_config.h"

#include <boost/test/unit_test.hpp>

#include <mms/string.h>
#include <mms/vector.h>
#include <mms/map.h>
#include <mms/set.h>
#include <mms/writer.h>
#include <mms/copy.h>
#include <iostream>
#include <sstream>
#include <functional>
#include <boost/lexical_cast.hpp>

#include <boost/assign/std/vector.hpp>
#include "tools.h"

template <class T1, class T2, class T3>
struct TraverseSimple {

    T1 v1;
    T2 v2;
    T3 v3;

    template<class A> void traverseFields(A a) const { a(v1)(v2)(v3); }
    typedef TraverseSimple<T1, T2, T3> MmappedType;
};

template <class T1, class T2, class T3>
bool operator == (const TraverseSimple<T1, T2, T3>& lhs,
                  const TraverseSimple<T1, T2, T3>& rhs)
{
    return lhs.v1 == rhs.v1 && lhs.v2 == rhs.v2 && lhs.v3 == rhs.v3;
}

template <class T1, class T2, class T3>
TraverseSimple<T1, T2, T3> genTraverseSimple(int seed)
{
    TraverseSimple<T1, T2, T3> pod;
    pod.v1 = GenT<T1>()(seed);
    pod.v2 = GenT<T2>()(seed * 57);
    pod.v3 = GenT<T3>()(seed * 1543);
    return pod;
}

template <class T1, class T2, class T3>
void testTraverseSimple(int seed)
{
    typedef TraverseSimple<T1, T2, T3> SIMPLE;
    SIMPLE podOrig = genTraverseSimple<T1, T2, T3>(seed);
    std::stringstream out;
    mms::Writer w(out);
    size_t ofs = mms::unsafeWrite(w, podOrig);
    BOOST_CHECK_EQUAL(w.pos(), sizeof(SIMPLE));
    BOOST_CHECK_EQUAL(ofs, 0);

    std::string buf = out.str();
    SIMPLE podReaded = *((const SIMPLE*) (buf.c_str() + ofs));
    BOOST_CHECK(podOrig == podReaded);

    SIMPLE copied;
    mms::copy(podReaded, copied);
    BOOST_CHECK(podOrig == copied);
}

BOOST_AUTO_TEST_CASE( pod_test )
{
    for(int seed = -1300; seed <= 157092; seed += 10212) {
        testTraverseSimple<int, int, int>(seed);
        testTraverseSimple<char, int, int>(seed);
        testTraverseSimple<int, char, int>(seed);
        testTraverseSimple<int, int, char>(seed);
        testTraverseSimple<int, size_t, int>(seed);
        testTraverseSimple<char, size_t, int>(seed);
        testTraverseSimple<int, size_t, char>(seed);
        testTraverseSimple<char, char, int>(seed);
        testTraverseSimple<char, char, char>(seed);
        testTraverseSimple<uint32_t, uint16_t, uint32_t>(seed);
        testTraverseSimple<uint32_t, char, uint32_t>(seed);
        testTraverseSimple<uint16_t, char, uint16_t>(seed);
    }
}


text:
package com.ibm.streamsx.topology.test.api;

import static com.ibm.streamsx.topology.test.api.IsolateTest.getContainerId;
import static com.ibm.streamsx.topology.test.api.IsolateTest.getContainerIdAppend;
import static com.ibm.streamsx.topology.test.api.IsolateTest.getContainerIds;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

import com.ibm.json.java.JSONArray;
import com.ibm.json.java.JSONObject;
import com.ibm.streams.operator.PERuntime;
import com.ibm.streamsx.topology.TStream;
import com.ibm.streamsx.topology.Topology;
import com.ibm.streamsx.topology.builder.JOperator;
import com.ibm.streamsx.topology.builder.JOperator.JOperatorConfig;
import com.ibm.streamsx.topology.context.StreamsContext;
import com.ibm.streamsx.topology.context.StreamsContextFactory;
import com.ibm.streamsx.topology.function.ToIntFunction;
import com.ibm.streamsx.topology.function.UnaryOperator;
import com.ibm.streamsx.topology.generator.spl.SPLGenerator;
import com.ibm.streamsx.topology.test.AllowAll;
import com.ibm.streamsx.topology.test.TestTopology;
import com.ibm.streamsx.topology.tester.Condition;
import com.ibm.streamsx.topology.tester.Tester;

public class LowLatencyTest extends TestTopology {
    @Test
    public void simpleLowLatencyTest() throws Exception{
        assumeTrue(SC_OK);
        assumeTrue(isMainRun());
        Topology topology = new Topology("lowLatencyTest");

        // Construct topology
        TStream<String> ss = topology.strings("hello");
        TStream<String> ss1 = ss.transform(getContainerId()).lowLatency();
        TStream<String> ss2 = ss1.transform(getContainerId()).endLowLatency();
        ss2.print();

        StreamsContextFactory.getStreamsContext(StreamsContext.Type.TOOLKIT).submit(topology).get();
    }

    @Test
    public void multipleRegionLowLatencyTest() throws Exception{
        assumeTrue(SC_OK);
        assumeTrue(isMainRun());
        Topology topology = new Topology("lowLatencyTest");

        // Construct topology
        TStream<String> ss = topology.strings("hello")
                .transform(getContainerId()).transform(getContainerId());

        TStream<String> ss1 = ss.transform(getContainerId()).lowLatency();
        TStream<String> ss2 = ss1.transform(getContainerId()).
                transform(getContainerId()).endLowLatency().transform(getContainerId());
        TStream<String> ss3 = ss2.transform(getContainerId()).lowLatency();
        ss3.transform(getContainerId()).transform(getContainerId())
            .endLowLatency().print();

        StreamsContextFactory.getStreamsContext(StreamsContext.Type.TOOLKIT).submit(topology).get();
    }

    @Test
    public void threadedPortTest() throws Exception{
        assumeTrue(isMainRun());
        Topology topology = new Topology("lowLatencyTest");

        // Construct topology
        TStream<String> ss = topology.strings("hello").lowLatency();
        TStream<String> ss1 = ss.transform(getContainerId());
        TStream<String> ss2 = ss1.transform(getContainerId()).endLowLatency();

        SPLGenerator generator = new SPLGenerator();
        JSONObject graph = topology.builder().complete();
        generator.generateSPL(graph);

        JSONArray ops = (JSONArray)graph.get("operators");
        for(Object opObj : ops){
            JSONObject op = (JSONObject)opObj;
            String lowLatencyTag = null;
            JSONObject placement = JOperatorConfig.getJSONItem(op, JOperatorConfig.PLACEMENT);
            if (placement != null)
                lowLatencyTag = (String) placement.get(JOperator.PLACEMENT_LOW_LATENCY_REGION_ID);
            String kind = (String)op.get("kind");
            JSONObject queue = (JSONObject) op.get("queue");
            if(queue != null && (lowLatencyTag!=null || lowLatencyTag.equals(""))){
                throw new IllegalStateException("Operator has threaded port when it shouldn't.");
            }
            if(queue != null
                    && kind.equals("com.ibm.streamsx.topology.functional.java::FunctionTransform")){
                throw new IllegalStateException("Transform operator expecting threaded port; none found.");
            }
        }
    }

    @Test
    public void testLowLatencySplit() throws Exception {

        // lowLatency().split() is an interesting case because split()
        // has >1 oports.

        final Topology topology = new Topology("testLowLatencySplit");

        int splitWidth = 3;
        String[] strs = {"ch0", "ch1", "ch2"};
        TStream<String> s1 = topology.strings(strs);

        s1 = s1.isolate();
        s1 = s1.lowLatency();
        /////////////////////////////////////

        // assume that if s1.modify and the split().[modify()] are
        // in the same PE, that s1.split() is in the same too
        TStream<String> s2 = s1.modify(unaryGetPEId());

        List<TStream<String>> splits = s1
                .split(splitWidth, roundRobinSplitter());

        List<TStream<String>> splitChResults = new ArrayList<>();
        for(int i = 0; i < splits.size(); i++) {
            splitChResults.add( splits.get(i).modify(unaryGetPEId()) );
        }

        TStream<String> splitChFanin = splitChResults.get(0).union(
                        new HashSet<>(splitChResults.subList(1, splitChResults.size())));

        /////////////////////////////////////
        TStream<String> all = splitChFanin.endLowLatency();

        Tester tester = topology.getTester();

        Condition<Long> uCount = tester.tupleCount(all, strs.length);

        Condition<List<String>> contents = tester.stringContents(all, "");
        Condition<List<String>> s2contents = tester.stringContents(s2, "");

        complete(tester, uCount, 10, TimeUnit.SECONDS);

        Set<String> peIds = new HashSet<>();
        peIds.addAll(contents.getResult());
        peIds.addAll(s2contents.getResult());

        assertEquals("peIds: "+peIds, 1, peIds.size() );
    }

    @SuppressWarnings("serial")
    static UnaryOperator<String> unaryGetPEId() {
        return new UnaryOperator<String>() {

            @Override
            public String apply(String v) {
                return PERuntime.getPE().getPEId().toString();
            }
        };
    }

    @SuppressWarnings("serial")
    private static ToIntFunction<String> roundRobinSplitter() {
        return new ToIntFunction<String>() {
            private int i;

            @Override
            public int applyAsInt(String s) {
                return i++;
            }
        };
    }

    @Test
    public void nestedTest() throws Exception {

        // ensure nested low latency yields all fns in the same container

        final Topology topology = new Topology("nestedTest");
        final Tester tester = topology.getTester();
        // getConfig().put(ContextProperties.KEEP_ARTIFACTS, true);

        String[] s1Strs = {"a"};
        TStream<String> s1 = topology.strings(s1Strs);

        TStream<String> s2 =
                s1
                .isolate()
                .lowLatency()
                    .modify(getContainerIdAppend())
                    .lowLatency()
                        .modify(getContainerIdAppend())
                    .endLowLatency()
                    .modify(getContainerIdAppend())
                .endLowLatency()
                ;

        // NOTE, this works in the sense that all end up in the same container,
        // but currently only because of the default fuse-island behavior.
        // There are two issues with the json:
        // a) the 3rd modify is missing a lowLatencyTag
        // b) the 2nd modify has a different tag than the first.
        //    logically it must net out to being in the same container,
        //    so its just easiest if they're the same tag.
        //    It's not clear that having them be different is an absolute wrong,
        //    it's just that it doesn't add any value and complicates things.

        // s2.print();

        Condition<Long> uCount = tester.tupleCount(s2.filter(new AllowAll<String>()), 1);
        Condition<List<String>> contents = tester.stringContents(
                s2.filter(new AllowAll<String>()), "");

        complete(tester, uCount, 10, TimeUnit.SECONDS);

        Set<String> ids = getContainerIds(contents.getResult());
        assertEquals("ids: "+ids, 1, ids.size());
    }

}


text:
package com.yllyx.clubs.service.user;

import com.yllyx.clubs.entity.User;

public interface IUserService
{
    int getByUserId(String userId);

    boolean addUser(User user);

    boolean invalidByName(String name);

    boolean invalidByNamePasswd(String name, String passwd);

    boolean invalidByEmail(String email);

    boolean invalidByEmailPasswd(String email, String passwd);

    boolean invalidByTelphone(String telphone);

    boolean invalidByTelphonePasswd(String telphone, String passwd);
}


text:
using System;

using Foundation;
using AppKit;
using System.Linq;
using NGraphics.Test;
using System.IO;
using System.Threading.Tasks;

namespace NGraphics.Mac.Test
{
	public partial class MainWindowController : NSWindowController
	{
		public MainWindowController (IntPtr handle) : base (handle)
		{
		}

		[Export ("initWithCoder:")]
		public MainWindowController (NSCoder coder) : base (coder)
		{
		}

		public MainWindowController () : base ("MainWindow")
		{
		}

		public override void AwakeFromNib ()
		{
			base.AwakeFromNib ();
			RunTestsAsync ();
		}

		async Task RunTestsAsync ()
		{
			var sdir = System.IO.Path.GetDirectoryName (Environment.GetCommandLineArgs () [0]);
			while (Directory.GetFiles (sdir, "NGraphics.sln").Length == 0)
				sdir = System.IO.Path.GetDirectoryName (sdir);
			PlatformTest.ResultsDirectory = System.IO.Path.Combine (sdir, "TestResults");
			PlatformTest.Platform = Platforms.Current;
			PlatformTest.OpenStream = File.OpenWrite;
			Environment.CurrentDirectory = PlatformTest.ResultsDirectory;

			var tat = typeof(NUnit.Framework.TestAttribute);
			var tfat = typeof(NUnit.Framework.TestFixtureAttribute);

			var types = typeof (DrawingTest).Assembly.GetTypes ();
			var tfts = types.Where (t => t.GetCustomAttributes (tfat, false).Length > 0);

			foreach (var t in tfts) {
				var test = Activator.CreateInstance (t);
				var ms = t.GetMethods ().Where (m => m.GetCustomAttributes (tat, true).Length > 0);
				foreach (var m in ms) {
					var r = m.Invoke (test, null);
					var ta = r as Task;
					if (ta != null)
						await ta;
				}
			}

			NSApplication.SharedApplication.Terminate (this);
		}

		public new MainWindow Window {
			get { return (MainWindow)base.Window; }
		}
	}
}


text:
!(function () {
	'use strict'
	function e(e, n, t) {
		e.classList.contains(t) ? (e.classList.remove(t), n.innerHTML = '▾') : (e.classList.add(t), n.innerHTML = '▸')
	}
	function n() {
		const n = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0]
		e(n, n, 'display-none')
	}
	function t() {
		const n = this.parentNode.getElementsByClassName('toggle-target')[0]
		const t = this.getElementsByClassName('icon')[0]
		e(n, t, 'display-none')
	}
	function s(e) {
		const n = document.getElementById(e)
		n && n.offsetHeight === 0 && n.parentNode.parentNode.classList.contains('display-none') && n.parentNode.parentNode.classList.remove('display-none')
	}
	function a() {
		s(this.hash.substring(1))
	}
	anchors.options.placement = 'left', anchors.add('h3').remove('.no-anchor')
	const o = document.getElementById('toc').getElementsByTagName('li')
	const i = document.getElementById('filter-input')
	i.addEventListener('keyup', e => {
		if (e.keyCode === 13)			{
			for (let n = 0; n < o.length; n++) {
				const t = o[n]
				if (!t.classList.contains('display-none')) {
					return location.replace(t.firstChild.href), e.preventDefault()
				}
			}
		}
		let s = function () {
			return !0
		}
		const a = i.value.toLowerCase()
		a.match(/^\s*$/) || (s = function (e) {
			return e.firstChild.innerHTML.toLowerCase().indexOf(a) !== -1
		})
		for (let r = 0; r < o.length; r++) {
			const l = o[r]
			const d = Array.from(l.getElementsByTagName('li'))
			s(l) || d.some(s) ? l.classList.remove('display-none') : l.classList.add('display-none')
		}
	})
	for (let r = document.getElementsByClassName('toggle-step-sibling'), l = 0; l < r.length; l++) {
		r[l].addEventListener('click', n)
	}
	for (let d = document.getElementsByClassName('toggle-sibling'), c = 0; c < d.length; c++) {
		d[c].addEventListener('click', t)
	}
	window.addEventListener('hashchange', () => {
		s(location.hash.substring(1))
	}), s(location.hash.substring(1))
	for (let g = document.getElementsByClassName('pre-open'), m = 0; m < g.length; m++) {
		g[m].addEventListener('mousedown', a, !1)
	}
})()


text:
/* eslint-disable react/prefer-stateless-function */

/**
*
* RecordButton
*
*/

import React from 'react';

class RecordButton extends React.Component {
  render() {
    const handleClick = (e) => {
      e.stopPropagation();
      if (this.props.recording) {
        this.props.onStopRecording.call(this);
      } else {
        this.props.onRecord.call(this);
      }
    };

    return (
      <div className="button-container">
        <button onClick={ handleClick } className="record"></button>
      </div>
    );
  }
}

RecordButton.propTypes = {
  onRecord: React.PropTypes.func.isRequired,
  onStopRecording: React.PropTypes.func.isRequired,
  recording: React.PropTypes.bool.isRequired,
};

export default RecordButton;


text:
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2)
int pthread_threadid_np(pthread_t, __uint64_t *);
#elif defined(__linux__)
#include <sys/syscall.h>
#elif defined(__NetBSD__)
#include <lwp.h>
#endif

static const char *const RETVAL_PREFIX = "retval:";
static const char *const SLEEP_PREFIX = "sleep:";
static const char *const STDERR_PREFIX = "stderr:";
static const char *const SET_MESSAGE_PREFIX = "set-message:";
static const char *const PRINT_MESSAGE_COMMAND = "print-message:";
static const char *const GET_DATA_ADDRESS_PREFIX = "get-data-address-hex:";
static const char *const GET_STACK_ADDRESS_COMMAND = "get-stack-address-hex:";
static const char *const GET_HEAP_ADDRESS_COMMAND = "get-heap-address-hex:";

static const char *const GET_CODE_ADDRESS_PREFIX = "get-code-address-hex:";
static const char *const CALL_FUNCTION_PREFIX = "call-function:";

static const char *const THREAD_PREFIX = "thread:";
static const char *const THREAD_COMMAND_NEW = "new";
static const char *const THREAD_COMMAND_PRINT_IDS = "print-ids";
static const char *const THREAD_COMMAND_SEGFAULT = "segfault";

static const char *const PRINT_PID_COMMAND = "print-pid";

static bool g_print_thread_ids = false;
static pthread_mutex_t g_print_mutex = PTHREAD_MUTEX_INITIALIZER;
static bool g_threads_do_segfault = false;

static pthread_mutex_t g_jump_buffer_mutex = PTHREAD_MUTEX_INITIALIZER;
static jmp_buf g_jump_buffer;
static bool g_is_segfaulting = false;

static char g_message[256];

static volatile char g_c1 = '0';
static volatile char g_c2 = '1';

static void print_pid() {
  fprintf(stderr, "PID: %d\n", getpid());
}

static void print_thread_id() {
// Put in the right magic here for your platform to spit out the thread id (tid)
// that debugserver/lldb-gdbserver would see as a TID. Otherwise, let the else
// clause print out the unsupported text so that the unit test knows to skip
// verifying thread ids.
#if defined(__APPLE__)
  __uint64_t tid = 0;
  pthread_threadid_np(pthread_self(), &tid);
  printf("%" PRIx64, tid);
#elif defined(__linux__)
  // This is a call to gettid() via syscall.
  printf("%" PRIx64, static_cast<uint64_t>(syscall(__NR_gettid)));
#elif defined(__NetBSD__)
  // Technically lwpid_t is 32-bit signed integer
  printf("%" PRIx64, static_cast<uint64_t>(_lwp_self()));
#else
  printf("{no-tid-support}");
#endif
}

static void signal_handler(int signo) {
  const char *signal_name = nullptr;
  switch (signo) {
  case SIGUSR1:
    signal_name = "SIGUSR1";
    break;
  case SIGSEGV:
    signal_name = "SIGSEGV";
    break;
  default:
    signal_name = nullptr;
  }

  // Print notice that we received the signal on a given thread.
  pthread_mutex_lock(&g_print_mutex);
  if (signal_name)
    printf("received %s on thread id: ", signal_name);
  else
    printf("received signo %d (%s) on thread id: ", signo, strsignal(signo));
  print_thread_id();
  printf("\n");
  pthread_mutex_unlock(&g_print_mutex);

  // Reset the signal handler if we're one of the expected signal handlers.
  switch (signo) {
  case SIGSEGV:
    if (g_is_segfaulting) {
      // Fix up the pointer we're writing to.  This needs to happen if nothing
      // intercepts the SIGSEGV (i.e. if somebody runs this from the command
      // line).
      longjmp(g_jump_buffer, 1);
    }
    break;
  case SIGUSR1:
    if (g_is_segfaulting) {
      // Fix up the pointer we're writing to.  This is used to test gdb remote
      // signal delivery. A SIGSEGV will be raised when the thread is created,
      // switched out for a SIGUSR1, and then this code still needs to fix the
      // seg fault. (i.e. if somebody runs this from the command line).
      longjmp(g_jump_buffer, 1);
    }
    break;
  }

  // Reset the signal handler.
  sig_t sig_result = signal(signo, signal_handler);
  if (sig_result == SIG_ERR) {
    fprintf(stderr, "failed to set signal handler: errno=%d\n", errno);
    exit(1);
  }
}

static void swap_chars() {
  g_c1 = '1';
  g_c2 = '0';

  g_c1 = '0';
  g_c2 = '1';
}

static void hello() {
  pthread_mutex_lock(&g_print_mutex);
  printf("hello, world\n");
  pthread_mutex_unlock(&g_print_mutex);
}

static void *thread_func(void *arg) {
  static pthread_mutex_t s_thread_index_mutex = PTHREAD_MUTEX_INITIALIZER;
  static int s_thread_index = 1;

  pthread_mutex_lock(&s_thread_index_mutex);
  const int this_thread_index = s_thread_index++;
  pthread_mutex_unlock(&s_thread_index_mutex);

  if (g_print_thread_ids) {
    pthread_mutex_lock(&g_print_mutex);
    printf("thread %d id: ", this_thread_index);
    print_thread_id();
    printf("\n");
    pthread_mutex_unlock(&g_print_mutex);
  }

  if (g_threads_do_segfault) {
    // Sleep for a number of seconds based on the thread index.
    // TODO add ability to send commands to test exe so we can
    // handle timing more precisely.  This is clunky.  All we're
    // trying to do is add predictability as to the timing of
    // signal generation by created threads.
    int sleep_seconds = 2 * (this_thread_index - 1);
    while (sleep_seconds > 0)
      sleep_seconds = sleep(sleep_seconds);

    // Test creating a SEGV.
    pthread_mutex_lock(&g_jump_buffer_mutex);
    g_is_segfaulting = true;
    int *bad_p = nullptr;
    if (setjmp(g_jump_buffer) == 0) {
      // Force a seg fault signal on this thread.
      *bad_p = 0;
    } else {
      // Tell the system we're no longer seg faulting.
      // Used by the SIGUSR1 signal handler that we inject
      // in place of the SIGSEGV so it only tries to
      // recover from the SIGSEGV if this seg fault code
      // was in play.
      g_is_segfaulting = false;
    }
    pthread_mutex_unlock(&g_jump_buffer_mutex);

    pthread_mutex_lock(&g_print_mutex);
    printf("thread ");
    print_thread_id();
    printf(": past SIGSEGV\n");
    pthread_mutex_unlock(&g_print_mutex);
  }

  int sleep_seconds_remaining = 60;
  while (sleep_seconds_remaining > 0) {
    sleep_seconds_remaining = sleep(sleep_seconds_remaining);
  }

  return nullptr;
}

int main(int argc, char **argv) {
  lldb_enable_attach();

  std::vector<pthread_t> threads;
  std::unique_ptr<uint8_t[]> heap_array_up;
  int return_value = 0;

  // Set the signal handler.
  sig_t sig_result = signal(SIGALRM, signal_handler);
  if (sig_result == SIG_ERR) {
    fprintf(stderr, "failed to set SIGALRM signal handler: errno=%d\n", errno);
    exit(1);
  }

  sig_result = signal(SIGUSR1, signal_handler);
  if (sig_result == SIG_ERR) {
    fprintf(stderr, "failed to set SIGUSR1 handler: errno=%d\n", errno);
    exit(1);
  }

  sig_result = signal(SIGSEGV, signal_handler);
  if (sig_result == SIG_ERR) {
    fprintf(stderr, "failed to set SIGUSR1 handler: errno=%d\n", errno);
    exit(1);
  }

  // Process command line args.
  for (int i = 1; i < argc; ++i) {
    if (std::strstr(argv[i], STDERR_PREFIX)) {
      // Treat remainder as text to go to stderr.
      fprintf(stderr, "%s\n", (argv[i] + strlen(STDERR_PREFIX)));
    } else if (std::strstr(argv[i], RETVAL_PREFIX)) {
      // Treat as the return value for the program.
      return_value = std::atoi(argv[i] + strlen(RETVAL_PREFIX));
    } else if (std::strstr(argv[i], SLEEP_PREFIX)) {
      // Treat as the amount of time to have this process sleep (in seconds).
      int sleep_seconds_remaining = std::atoi(argv[i] + strlen(SLEEP_PREFIX));

      // Loop around, sleeping until all sleep time is used up.  Note that
      // signals will cause sleep to end early with the number of seconds
      // remaining.
      for (int i = 0; sleep_seconds_remaining > 0; ++i) {
        sleep_seconds_remaining = sleep(sleep_seconds_remaining);
        // std::cout << "sleep result (call " << i << "): " <<
        // sleep_seconds_remaining << std::endl;
      }
    } else if (std::strstr(argv[i], SET_MESSAGE_PREFIX)) {
      // Copy the contents after "set-message:" to the g_message buffer.
      // Used for reading inferior memory and verifying contents match
      // expectations.
      strncpy(g_message, argv[i] + strlen(SET_MESSAGE_PREFIX),
              sizeof(g_message));

      // Ensure we're null terminated.
      g_message[sizeof(g_message) - 1] = '\0';

    } else if (std::strstr(argv[i], PRINT_MESSAGE_COMMAND)) {
      pthread_mutex_lock(&g_print_mutex);
      printf("message: %s\n", g_message);
      pthread_mutex_unlock(&g_print_mutex);
    } else if (std::strstr(argv[i], GET_DATA_ADDRESS_PREFIX)) {
      volatile void *data_p = nullptr;

      if (std::strstr(argv[i] + strlen(GET_DATA_ADDRESS_PREFIX), "g_message"))
        data_p = &g_message[0];
      else if (std::strstr(argv[i] + strlen(GET_DATA_ADDRESS_PREFIX), "g_c1"))
        data_p = &g_c1;
      else if (std::strstr(argv[i] + strlen(GET_DATA_ADDRESS_PREFIX), "g_c2"))
        data_p = &g_c2;

      pthread_mutex_lock(&g_print_mutex);
      printf("data address: %p\n", data_p);
      pthread_mutex_unlock(&g_print_mutex);
    } else if (std::strstr(argv[i], GET_HEAP_ADDRESS_COMMAND)) {
      // Create a byte array if not already present.
      if (!heap_array_up)
        heap_array_up.reset(new uint8_t[32]);

      pthread_mutex_lock(&g_print_mutex);
      printf("heap address: %p\n", heap_array_up.get());
      pthread_mutex_unlock(&g_print_mutex);
    } else if (std::strstr(argv[i], GET_STACK_ADDRESS_COMMAND)) {
      pthread_mutex_lock(&g_print_mutex);
      printf("stack address: %p\n", &return_value);
      pthread_mutex_unlock(&g_print_mutex);
    } else if (std::strstr(argv[i], GET_CODE_ADDRESS_PREFIX)) {
      void (*func_p)() = nullptr;

      if (std::strstr(argv[i] + strlen(GET_CODE_ADDRESS_PREFIX), "hello"))
        func_p = hello;
      else if (std::strstr(argv[i] + strlen(GET_CODE_ADDRESS_PREFIX),
                           "swap_chars"))
        func_p = swap_chars;

      pthread_mutex_lock(&g_print_mutex);
      printf("code address: %p\n", func_p);
      pthread_mutex_unlock(&g_print_mutex);
    } else if (std::strstr(argv[i], CALL_FUNCTION_PREFIX)) {
      void (*func_p)() = nullptr;

      // Defaut to providing the address of main.
      if (std::strcmp(argv[i] + strlen(CALL_FUNCTION_PREFIX), "hello") == 0)
        func_p = hello;
      else if (std::strcmp(argv[i] + strlen(CALL_FUNCTION_PREFIX),
                           "swap_chars") == 0)
        func_p = swap_chars;
      else {
        pthread_mutex_lock(&g_print_mutex);
        printf("unknown function: %s\n",
               argv[i] + strlen(CALL_FUNCTION_PREFIX));
        pthread_mutex_unlock(&g_print_mutex);
      }
      if (func_p)
        func_p();
    } else if (std::strstr(argv[i], THREAD_PREFIX)) {
      // Check if we're creating a new thread.
      if (std::strstr(argv[i] + strlen(THREAD_PREFIX), THREAD_COMMAND_NEW)) {
        // Create a new thread.
        pthread_t new_thread;
        const int err =
            ::pthread_create(&new_thread, nullptr, thread_func, nullptr);
        if (err) {
          fprintf(stderr, "pthread_create() failed with error code %d\n", err);
          exit(err);
        }
        threads.push_back(new_thread);
      } else if (std::strstr(argv[i] + strlen(THREAD_PREFIX),
                             THREAD_COMMAND_PRINT_IDS)) {
        // Turn on thread id announcing.
        g_print_thread_ids = true;

        // And announce us.
        pthread_mutex_lock(&g_print_mutex);
        printf("thread 0 id: ");
        print_thread_id();
        printf("\n");
        pthread_mutex_unlock(&g_print_mutex);
      } else if (std::strstr(argv[i] + strlen(THREAD_PREFIX),
                             THREAD_COMMAND_SEGFAULT)) {
        g_threads_do_segfault = true;
      } else {
        // At this point we don't do anything else with threads.
        // Later use thread index and send command to thread.
      }
    } else if (std::strstr(argv[i], PRINT_PID_COMMAND)) {
        print_pid();
    } else {
      // Treat the argument as text for stdout.
      printf("%s\n", argv[i]);
    }
  }

  // If we launched any threads, join them
  for (std::vector<pthread_t>::iterator it = threads.begin();
       it != threads.end(); ++it) {
    void *thread_retval = nullptr;
    const int err = ::pthread_join(*it, &thread_retval);
    if (err != 0)
      fprintf(stderr, "pthread_join() failed with error code %d\n", err);
  }

  return return_value;
}