text:
<!DOCTYPE html>

  <title>My New App</title>

  <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" href="css/index.css" />

    <my-new-app-toolbar></my-new-app-toolbar>


text:
* [Description](#description)
* [Function Index](#index)
* [Function Details](#functions)

Interface library for managing probes.

__Behaviours:__ [`exometer_entry`](exometer_entry.md).

__This module defines the `exometer_probe` behaviour.__
 Required callback functions: `behaviour/0`, `probe_init/3`, `probe_terminate/1`, `probe_setopts/3`, `probe_update/2`, `probe_get_value/2`, `probe_get_datapoints/1`, `probe_reset/1`, `probe_sample/1`, `probe_handle_msg/2`, `probe_code_change/3`.

## Description ##

This library contains the main API for accessing all probes
executing in exometer.

All exported functions in the `exomter_probe` module are invoked
by the `exometer` module; a developer will not have to call
`exometer_probe` functions directly.

A probe is an implementation of the `exometer_probe` behavior
which runs in its own process in order to collect data to be
handled and reported by exometer. The implementation will be
invoked through the `exomoeter_probe` module, which, as stated
above, in its turn is invoked by the `exometer` module.

A custom exometer probe is invoked by mapping a type to the module
name of the custom exometer probe module. All metrics created with the
given type will trigger the invocation of the new probe module. See
[Configuring type - entry maps](#Configuring_type_-_entry_maps) for details on how to setup
such maps.

If the data can be collected at a high speed, and without
blocking, an `exometer_entry` implementation can be used instead
to do the gathering in-process.

A probe is created throgh the `exomter_probe:new/3` call, which in
its turn is called by `exometer:new/3`. During probe creation, a
new process is spawned to handle the probe and call its
implementation.  While the created process is not a gen_server, it
behaves similarly and provides a state to all implementation
calls.

Once running, the probe collects data from a subsystem, such as
`/proc`, `sysfs`, and `netlink`, through timer-based calls to
`probe_sample/1` or explicit calls to `probe_update/2`.

A probe implementation can support any number of data points,
where each data point is a specifric sample from the probe. For
example, a probe that measures network traffic would have
`rx_packets`, `tx_packets`, `errors`, `dropped`, and other data
points reported by `ifconfig(8)` and `ip(8)`.

Values are retrieved from the probe through the `probe_get_value/2`
call, which specifies the data points to be returned. The probe is
expected to gather the given data points and return them to the
caller.

### The probe callback interface ###

The following functions are to be implemented and exported by a probe
implementation.

#### behaviour/0 ####

The `behaviour/0` function for an entry implementation should return
the atom `probe`. This function will be involved by the
exometer system in order to determine if a callback is
an entry or a probe.

#### probe_init/3 ####

The `probe_init/3` function is invoked as follows:

```erlang

       probe_init(Name, Type, Options)
```

The implementation shall initiate the probe, create the
necessary state, and return it for furure access
through `probe_update/2`, `probe_sample/1` and `get_value/2` calls.

The arguments are as follows:

+ `Name`
Specifies the name of the metric to be created as a list of atoms.

+ `Type`
Specifies the type provided to the `exometer:new/3` call (before it
was translated by the type - exometer probe map). It can be used if several
different types are mapped to the same probe module.

+ `Options`
Specifies an option list that contains additional setup directives to
the probe. The actual options to support are a combination of the
standard options, described below, and probe specific options
processed by `probe_init/3`.

Standard options are processed directly by `new/3`, before
`probe_init/3` is calledm and are as follows:

+ `{priority, P}`
Will be forwarded by the probe's process to `erlang:process_flag/2`.

+ `{min_heap_size, S}`
Will be forwarded by the probe's process to `erlang:process_flag/2`.

+ `{min_bin_vheap_size, S}`
Will be forwarded by the probe's process to `erlang:process_flag/2`.

+ `{sensitive, true | false}`
Will be forwarded by the probe's process to `erlang:process_flag/2`.

+ `{sample_interval, t}`
Specifies the interval, in milliseconds, that `exometer_probe:sample/1`.
should be invoked at.

The `probe_init/3` implementation is invoked by `exometer:new/3`,
which calls `exometer_probe:new/3`, which invokes the probe
implementation..

The `probe_init/3` function shall return `{ok, State}` where State
is a tuple that will be provided as a the `State` argument to all
future probe implementation calls for the metric.

If the `sample_interval` option has been specified in `Opts`,
probe_sample/2' will be invoked immediately after `probe_init/2`
returns to retrieve a first sample. After that, `probe_sample/2`
will repeatedly will be called by the probe process at the
millisecond-specified interval.

Should `probe_init/3` return antyhing else but `{ok, State}`,
invoking `new/3` call will fail.

#### probe_terminate/1 ####

The `probe_terminate/1` function is invoked as follows:

```erlang

       probe_terminate(State)
```

The custom probe shall release any resources associated with the
given state and return `ok`.

The arguments are as follows:

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

The `probe_terminate/1` implementation is invoked by `exometer:delete/1`, which
calls `exometer_probe:delete/3`, which invokes the probe
implementation.

#### probe_setopts/3 ####

The `probe_setopts/2` function is invoked as follows:

```erlang

       probe_setopts(Entry, Opts, State)
```

The `probe_setopts/4` implementation is invoked by
`exometer:setopts/3`, which calls `exometer_probe:setopts/3`,
which invokes the probe implementation.

The implementation of this function shall modify the options of a
probe. The `setopts/3` function, which will process standard
options before invoking `probe_setopts/4` with the remaining
options. See the documentation for `probe_init/3` for details.

The arguments are as follows:

+ `Entry`
The (opaque) exometer entry record. See [`exometer_info`](exometer_info.md) for
information on how to inspect the data structure.

+ `Opts`
The probe-specific options to be processed.

+ `Status`
The new status of the entry.

+ `State`
The probe state, originally returned by `probe_init/3` and subsequently
modified by other probe implementation calls.

This function shall return `{ok, NewState}` where `NewState` is
the modified probe state that incorporates the new options.

#### probe_update/2 ####

The `probe_update/2` function is invoked as follows:

```erlang

       probe_update(Value, State)
```

Incorporate a new value into the metric maintained by the metric.

The arguments are as follows:

+ `Value`
The value to integrate.

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

This function can be called outside the periodic `probe_sample/1/`
call to have the probe process a value given in `Value`.

The `probe_update/2` implementation is invoked by `exometer:update/2`, which
calls `exometer_probe:update/4`, which invokes the probe
implementation.

Once processed, `probe_update/2` shall return `{ok, NewState}`,
where `NewState` contains the new probe state with the processed
value.

#### probe_get_value/2 ####

The `probe_get_value/2` function is invoked as follows:

```erlang

       probe_get_value(DataPoints, State)
```

The `probe_get_value/2` implementation shall retrieve the value of
one or more data points from the probe.

The arguments are as follows:

+ `DataPoints`
List of data point atoms to retrieve values for.

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

The `probe_get_value/2` implementation is invoked by
`exometer:get_value/2`, which calls `exometer_probe:get_value/4`,
which invokes the probe implementation.

If `exometer:get_value/2` is invoked with `default` as a single
data point, the probe's `probe_get_datapoints/1` function will be
called to retrieve all data points supported by the probe
implementation. `probe_get_value/2` will then be called with the
returned set of data points provided as an argument.

This function shall return the value of all data points provided in
`DataPoints`, given that they are supported.

The list in the returned tuple shall have the format:

```erlang

       [{ DP, Val}, ...]
```

Where `DP` one of the data points in the `DataPoints` argument, and
`Val` is the value of that data point.

If one of the argument-provided data points are not supported by the probe,
the tuple returned for that data point shall be `{ DP, {error, undefined}`.

For example, if the provided `DataPoint` argument is set to `[ min,
max, xyzzy ]`, and only `min` and `max` are supported
by the probe, the returned list shall look like below:

```erlang

       [{ min, 0.1265 }, { max, 3338.21 }, { xyzzy, { error, unsupported } ]
```

The `probe_get_value/2` implementation shall return `{ok, List}`,
where `List` is the list of data points and their values described
above. No new state is returned by this function.

#### probe_get_datapoints/1 ####

The `probe_get_datapoints/1` function is invoked as follows:

```erlang

       probe_get_datapoints(State)
```

The `probe_get_datapoints/1` shall return a list with all data points
supported by the probe

The arguments are as follows:

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

The `probe_get_datapoints/1` implementation is invoked by
`exometer:info/2`, which calls `exometer_probe:get_datapoints/3`,
which invokes the probe implementation.

In cases where `exometer:get_value/2` is called with `default` as a
single data point, `probe_get_datapoints/1` is also called to
retrieve a list of all supported data points, which is then
forwarded to `probe_get_value/2`.

The implementation of `probe_get_datapoints/1` shall return `{ok, DpList}`,
where `DpList` is a list of data point atoms supported by the probe.

#### probe_reset/1 ####

The `probe_reset/1` function is invoked as follows:

```erlang

       probe_reset(State)
```

The `probe_reset/1` shall reset the state of the probe to its initial state.

The arguments are as follows:

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

The `probe_reset/1` implementation is invoked by
`exometer:reset/1`, which calls `exometer_probe:reset/3`, which
invokes the probe implementation.

The implementation of `probe_reset/1` shall return `{ok,
NewState}`, where `NewState` contains the reset state of the probe.

#### probe_sample/1 ####

The `probe_sample/1` function is invoked as follows:

```erlang

       probe_sample(State)
```

The `probe_sample/1` implementation shall sample data from the
subsystem the probe is integrated with.

The arguments are as follows:

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

When invoked, `probe_sample/1` is expected to interface the
sub-system (/proc, /sysfs, etc) monitored by the probe, extract the
relevant data from it, and return an updated probe state that
incorporates the extracted data.

The `probe_sample/1` function is invoked by the probe thread at
intervals specified by the `{sample_interval, Intv}` option
provided to `exometer_probe:new/3`. If this option is missing, or
set to infinity, `probe_sample/1` will never be called.

The implementation of `probe_sample/1` shall return `{ok,
NewState}`, where `NewState` contains the new state of the probe
with the sampled data integrated into it.

#### probe_handle_msg/2 ####

The `probe_handle_msg/2` function is invoked as follows:

```erlang

       probe_handle_msg(Msg, State)
```

The `probe_handle_msg/1` is invoked to process messages received
by the probe process.

The arguments are as follows:

+ `State`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

+ `Msg`
The probe state, originally returned by `probe_init/3` and subsequentially
modified by other probe implementation calls.

The implementation of this function will be called by the probe's
process when it receives a message that is not recognized by the
internal receive loop.

The implementation of `probe_handle_msg/2` shall return `{ok,
NewState}`, where `NewState` contains the new state of the probe
that reflects the processed message.

### Fault tolerance ###

Probes are supervised by the `exometer_admin` process, and can be restarted
after a crash. Restart parameters are provided via the option
`{restart, Params}`, where `Params` is a list of `{Frequency, Action}`
tuples. `Frequency` is either `{Count, MilliSecs}` or `'_`', and
the corresponding `Action :: restart | disable | delete` will be performed
if the frequency of restarts falls within the given limit.

For example, `[{{3, 1000}, restart}]` will allow 3 restarts within a 1-second
window. The matching is performed from top to bottom, and the first matching
pattern is acted upon. If no matching pattern is found, the default action
is `delete`. A pattern `{'_', Action}` acts as a catch-all, and should
be put last in the list.

It is also possible to specify `{{Count, '_'}, Action}`, which means
that a total of `Count` restarts is permitted, regardless of how far apart
they are. The count is reset after each restart.

Example:

```erlang

    {restart, [{{3,1000}, restart},   % up to 3 restarts within 1 sec
               {{4,'_'} , disable},   % a total of up to 4 restarts
               {'_'     , delete}]}   % anything else
```

## Function Index ##

behaviour/0

delete/3

get_datapoints/3

get_value/3

get_value/4

new/3

reset/3

restart/4

sample/3

setopts/3

update/4

## Function Details ##

### behaviour/0 ###

`behaviour() -> any()`

### delete/3 ###

`delete(Name, Type, Pid) -> any()`

### get_datapoints/3 ###

`get_datapoints(Name, Type, Pid) -> any()`

### get_value/3 ###

`get_value(Name, Type, Pid) -> any()`

### get_value/4 ###

`get_value(Name, Type, Pid, DataPoints) -> any()`

### new/3 ###

`new(Name, Type, Opts) -> any()`

### reset/3 ###

`reset(Name, Type, Pid) -> any()`

### restart/4 ###

`restart(Name, Module, Error, SpawnOpts) -> any()`

### sample/3 ###

`sample(Name, Type, Pid) -> any()`

### setopts/3 ###

`setopts(Exometer_entry, Opts, Status) -> any()`

### update/4 ###

`update(Name, Value, Type, Pid) -> any()`

redpajama_set_name: RedPajamaGithub


text:
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.CollisionShapes;
using BEPUphysics.CollisionShapes.ConvexShapes;
using System.Collections.Generic;
using System.Diagnostics;
using BEPUutilities;

namespace BEPUphysicsDemos.Demos
{
    /// <summary>
    /// Compound bodies are created from other entities to make concave shapes.
    /// </summary>
    public class CompoundBodiesDemo : StandardDemo
    {
        /// <summary>
        /// Constructs a new demo.
        /// </summary>
        /// <param name="game">Game owning this demo.</param>
        public CompoundBodiesDemo(DemosGame game)
            : base(game)
        {

            //Build the first body
            var bodies = new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(0, 1, 0), 1),
                new CompoundShapeEntry(new ConeShape(2, .5f), new Vector3(1, 1, 0), 1),
                new CompoundShapeEntry(new SphereShape(.5f), new Vector3(-1, 1, 0), 1)
            };
            var cb1 = new CompoundBody(bodies, 45);

            //Build the second body
            bodies = new List<CompoundShapeEntry>
            {
                new CompoundShapeEntry(new BoxShape(1,1,1), new Vector3(0, 3, 0), 1),
                new CompoundShapeEntry(new BoxShape(1,1,1), new Vector3(1, 3.5f, 0), 1),
            };
            var cb2 = new CompoundBody(bodies, 4);

            bodies = new List<CompoundShapeEntry>();
            //Build the third Braum's-fry style body
            for (int k = 0; k < 7; k++)
            {
                bodies.Add(new CompoundShapeEntry(new BoxShape(1, 1, 1), new Vector3(-4 + k * .7f, 2 + .7f * k, 2 + k * .2f), 1));
            }
            var cb3 = new CompoundBody(bodies, 7);

            //Add them all to the space
            Space.Add(cb3);
            Space.Add(cb2);
            Space.Add(cb1);

            Space.Add(new Box(new Vector3(0, -.5f, 0), 10, 1, 10));
            game.Camera.Position = new Vector3(0, 3, 15);

        }

        /// <summary>
        /// Gets the name of the simulation.
        /// </summary>
        public override string Name
        {
            get { return "Compound Bodies"; }
        }
    }
}


text:
#
#  Makefile for the Duktape development repo
#
#  This Makefile is intended for ONLY internal Duktape development
#  on Linux (or other UNIX-like operating systems), and covers:
#
#    - building the Duktape source distributable
#    - running test cases
#    - building the duktape.org website
#
#  The Makefile now also works in a very limited fashion with Cygwin,
#  you can 'make dist' as long as you have enough software installed.
#  The closure compiler requires a working JDK installation (JRE is
#  not enough, JAVA_HOME must point to the JDK), and a working Apache
#  'ant' command.
#
#  The source distributable has more platform neutral example Makefiles
#  for end user projects (though an end user should really just use their
#  own Makefile).
#
#  YOU SHOULD NOT COMPILE DUKTAPE WITH THIS MAKEFILE IN YOUR PROJECT!
#
#  Duktape command line tools are built by first creating a source dist
#  directory, and then using the sources from the dist directory for
#  compilation.  This is as close as possible to the sources used by an
#  end user, at the risk of accidentally polluting the dist directory.
#
#  When creating actual distributables, always clean first.
#
#  External projects are downloaded on-the-fly.  Clone git repos shallowly
#  (--depth 1) whenever possible.  With build-critical resources, use a
#  specific version instead of "trunk".
#
#  The makefile should work with -jN except for the 'clean' target, use:
#
#    $ make clean; make -j4
#

# A few commands which may need to be edited.  NodeJS is sometimes found
# as 'nodejs', sometimes as 'node'; sometimes 'node' is unrelated to NodeJS
# so check 'nodejs' first.
GIT:=$(shell which git)
NODE:=$(shell which nodejs node | head -1)
WGET:=$(shell which wget)
JAVA:=$(shell which java)
VALGRIND:=$(shell which valgrind)
PYTHON:=$(shell which python)

# Scrape version from the public header; convert from e.g. 10203 -> '1.2.3'
DUK_VERSION:=$(shell cat src/duk_api_public.h.in | grep define | grep DUK_VERSION | tr -s ' ' ' ' | cut -d ' ' -f 3 | tr -d 'L')
DUK_MAJOR:=$(shell echo "$(DUK_VERSION) / 10000" | bc)
DUK_MINOR:=$(shell echo "$(DUK_VERSION) % 10000 / 100" | bc)
DUK_PATCH:=$(shell echo "$(DUK_VERSION) % 100" | bc)
DUK_VERSION_FORMATTED:=$(DUK_MAJOR).$(DUK_MINOR).$(DUK_PATCH)
GIT_BRANCH:=$(shell git rev-parse --abbrev-ref HEAD)
GIT_DESCRIBE:=$(shell git describe --always --dirty)
ifeq ($(GIT_BRANCH),master)
GIT_INFO:=$(GIT_DESCRIBE)
else
GIT_INFO:=$(GIT_DESCRIBE)-$(GIT_BRANCH)
endif
BUILD_DATETIME:=$(shell date +%Y%m%d%H%M%S)

DISTSRCSEP = dist/src-separate
DISTSRCCOM = dist/src
DISTCMD = dist/examples/cmdline

DUKTAPE_SOURCES_COMBINED =	\
	$(DISTSRCCOM)/duktape.c

DUKTAPE_SOURCES_SEPARATE =	\
	$(DISTSRCSEP)/duk_util_hashbytes.c \
	$(DISTSRCSEP)/duk_util_hashprime.c \
	$(DISTSRCSEP)/duk_util_bitdecoder.c \
	$(DISTSRCSEP)/duk_util_bitencoder.c \
	$(DISTSRCSEP)/duk_util_tinyrandom.c \
	$(DISTSRCSEP)/duk_util_bufwriter.c \
	$(DISTSRCSEP)/duk_util_misc.c \
	$(DISTSRCSEP)/duk_alloc_default.c \
	$(DISTSRCSEP)/duk_debug_macros.c \
	$(DISTSRCSEP)/duk_debug_vsnprintf.c \
	$(DISTSRCSEP)/duk_debug_heap.c \
	$(DISTSRCSEP)/duk_debug_fixedbuffer.c \
	$(DISTSRCSEP)/duk_error_macros.c \
	$(DISTSRCSEP)/duk_error_longjmp.c \
	$(DISTSRCSEP)/duk_error_throw.c \
	$(DISTSRCSEP)/duk_error_augment.c \
	$(DISTSRCSEP)/duk_error_misc.c \
	$(DISTSRCSEP)/duk_heap_misc.c \
	$(DISTSRCSEP)/duk_heap_memory.c \
	$(DISTSRCSEP)/duk_heap_alloc.c \
	$(DISTSRCSEP)/duk_heap_refcount.c \
	$(DISTSRCSEP)/duk_heap_markandsweep.c \
	$(DISTSRCSEP)/duk_heap_hashstring.c \
	$(DISTSRCSEP)/duk_heap_stringtable.c \
	$(DISTSRCSEP)/duk_heap_stringcache.c \
	$(DISTSRCSEP)/duk_hstring_misc.c \
	$(DISTSRCSEP)/duk_hthread_misc.c \
	$(DISTSRCSEP)/duk_hthread_alloc.c \
	$(DISTSRCSEP)/duk_hthread_builtins.c \
	$(DISTSRCSEP)/duk_hthread_stacks.c \
	$(DISTSRCSEP)/duk_hobject_alloc.c \
	$(DISTSRCSEP)/duk_hobject_class.c \
	$(DISTSRCSEP)/duk_hobject_enum.c \
	$(DISTSRCSEP)/duk_hobject_props.c \
	$(DISTSRCSEP)/duk_hobject_finalizer.c \
	$(DISTSRCSEP)/duk_hobject_pc2line.c \
	$(DISTSRCSEP)/duk_hobject_misc.c \
	$(DISTSRCSEP)/duk_hbuffer_alloc.c \
	$(DISTSRCSEP)/duk_hbuffer_ops.c \
	$(DISTSRCSEP)/duk_hbufferobject_misc.c \
	$(DISTSRCSEP)/duk_unicode_tables.c \
	$(DISTSRCSEP)/duk_unicode_support.c \
	$(DISTSRCSEP)/duk_debugger.c \
	$(DISTSRCSEP)/duk_builtins.c \
	$(DISTSRCSEP)/duk_js_ops.c \
	$(DISTSRCSEP)/duk_js_var.c \
	$(DISTSRCSEP)/duk_numconv.c \
	$(DISTSRCSEP)/duk_api_stack.c \
	$(DISTSRCSEP)/duk_api_heap.c \
	$(DISTSRCSEP)/duk_api_call.c \
	$(DISTSRCSEP)/duk_api_compile.c \
	$(DISTSRCSEP)/duk_api_bytecode.c \
	$(DISTSRCSEP)/duk_api_codec.c \
	$(DISTSRCSEP)/duk_api_memory.c \
	$(DISTSRCSEP)/duk_api_string.c \
	$(DISTSRCSEP)/duk_api_object.c \
	$(DISTSRCSEP)/duk_api_buffer.c \
	$(DISTSRCSEP)/duk_api_var.c \
	$(DISTSRCSEP)/duk_api_logging.c \
	$(DISTSRCSEP)/duk_api_debug.c \
	$(DISTSRCSEP)/duk_lexer.c \
	$(DISTSRCSEP)/duk_tval.c \
	$(DISTSRCSEP)/duk_js_call.c \
	$(DISTSRCSEP)/duk_js_executor.c \
	$(DISTSRCSEP)/duk_js_compiler.c \
	$(DISTSRCSEP)/duk_regexp_compiler.c \
	$(DISTSRCSEP)/duk_regexp_executor.c \
	$(DISTSRCSEP)/duk_bi_duktape.c \
	$(DISTSRCSEP)/duk_bi_thread.c \
	$(DISTSRCSEP)/duk_bi_thrower.c \
	$(DISTSRCSEP)/duk_bi_array.c \
	$(DISTSRCSEP)/duk_bi_boolean.c \
	$(DISTSRCSEP)/duk_bi_date.c \
	$(DISTSRCSEP)/duk_bi_date_unix.c \
	$(DISTSRCSEP)/duk_bi_date_windows.c \
	$(DISTSRCSEP)/duk_bi_error.c \
	$(DISTSRCSEP)/duk_bi_function.c \
	$(DISTSRCSEP)/duk_bi_global.c \
	$(DISTSRCSEP)/duk_bi_json.c \
	$(DISTSRCSEP)/duk_bi_math.c \
	$(DISTSRCSEP)/duk_bi_number.c \
	$(DISTSRCSEP)/duk_bi_object.c \
	$(DISTSRCSEP)/duk_bi_regexp.c \
	$(DISTSRCSEP)/duk_bi_string.c \
	$(DISTSRCSEP)/duk_bi_proxy.c \
	$(DISTSRCSEP)/duk_bi_buffer.c \
	$(DISTSRCSEP)/duk_bi_pointer.c \
	$(DISTSRCSEP)/duk_bi_logger.c \
	$(DISTSRCSEP)/duk_selftest.c \
	$(DISTSRCSEP)/duk_strings.c

# Use combined sources for testing etc.
DUKTAPE_SOURCES = $(DUKTAPE_SOURCES_COMBINED)
#DUKTAPE_SOURCES = $(DUKTAPE_SOURCES_SEPARATE)

# Duktape command line tool - example of a main() program, used
# for unit testing
DUKTAPE_CMDLINE_SOURCES = \
	$(DISTCMD)/duk_cmdline.c \
	dist/examples/alloc-logging/duk_alloc_logging.c \
	dist/examples/alloc-torture/duk_alloc_torture.c \
	dist/examples/alloc-hybrid/duk_alloc_hybrid.c \
	dist/examples/debug-trans-socket/duk_trans_socket.c

# Compiler setup for Linux
CC	= gcc
GXX	= g++

CCOPTS_FEATURES =
#CCOPTS_FEATURES += -DDUK_OPT_NO_PACKED_TVAL
#CCOPTS_FEATURES += -DDUK_OPT_FORCE_ALIGN=4
#CCOPTS_FEATURES += -DDUK_OPT_FORCE_ALIGN=8
#CCOPTS_FEATURES += -DDUK_OPT_FORCE_BYTEORDER=1      # little
#CCOPTS_FEATURES += -DDUK_OPT_FORCE_BYTEORDER=2      # middle
#CCOPTS_FEATURES += -DDUK_OPT_FORCE_BYTEORDER=3      # big
#CCOPTS_FEATURES += -DDUK_OPT_NO_REFERENCE_COUNTING
#CCOPTS_FEATURES += -DDUK_OPT_NO_MARK_AND_SWEEP
#CCOPTS_FEATURES += -DDUK_OPT_NO_VOLUNTARY_GC
CCOPTS_FEATURES += -DDUK_OPT_SEGFAULT_ON_PANIC       # segfault on panic allows valgrind to show stack trace on panic
CCOPTS_FEATURES += -DDUK_OPT_DPRINT_COLORS
CCOPTS_FEATURES += -DDUK_OPT_DPRINT_RDTSC
#CCOPTS_FEATURES += -DDUK_OPT_NO_FILE_IO
#CCOPTS_FEATURES += '-DDUK_OPT_PANIC_HANDLER(code,msg)={printf("*** %d:%s\n",(code),(msg));abort();}'
CCOPTS_FEATURES += -DDUK_OPT_SELF_TESTS
#CCOPTS_FEATURES += -DDUK_OPT_NO_TRACEBACKS
#CCOPTS_FEATURES += -DDUK_OPT_NO_PC2LINE
#CCOPTS_FEATURES += -DDUK_OPT_NO_VERBOSE_ERRORS
#CCOPTS_FEATURES += -DDUK_OPT_PARANOID_ERRORS
#CCOPTS_FEATURES += -DDUK_OPT_NO_AUGMENT_ERRORS
#CCOPTS_FEATURES += -DDUK_OPT_GC_TORTURE
#CCOPTS_FEATURES += -DDUK_OPT_SHUFFLE_TORTURE
#CCOPTS_FEATURES += -DDUK_OPT_REFZERO_FINALIZER_TORTURE
#CCOPTS_FEATURES += -DDUK_OPT_MARKANDSWEEP_FINALIZER_TORTURE
#CCOPTS_FEATURES += -DDUK_OPT_NO_MS_RESIZE_STRINGTABLE
CCOPTS_FEATURES += -DDUK_OPT_DEBUG_BUFSIZE=512
#CCOPTS_FEATURES += -DDUK_OPT_NO_STRICT_DECL
#CCOPTS_FEATURES += -DDUK_OPT_NO_REGEXP_SUPPORT
#CCOPTS_FEATURES += -DDUK_OPT_NO_OCTAL_SUPPORT
#CCOPTS_FEATURES += -DDUK_OPT_NO_SOURCE_NONBMP
#CCOPTS_FEATURES += -DDUK_OPT_STRICT_UTF8_SOURCE
#CCOPTS_FEATURES += -DDUK_OPT_NO_BROWSER_LIKE
#CCOPTS_FEATURES += -DDUK_OPT_NO_SECTION_B
CCOPTS_FEATURES += -DDUK_OPT_INTERRUPT_COUNTER
CCOPTS_FEATURES += -DDUK_OPT_DEBUGGER_SUPPORT
CCOPTS_FEATURES += -DDUK_OPT_DEBUGGER_FWD_PRINTALERT
CCOPTS_FEATURES += -DDUK_OPT_DEBUGGER_FWD_LOGGING
CCOPTS_FEATURES += -DDUK_OPT_DEBUGGER_DUMPHEAP
#CCOPTS_FEATURES += -DDUK_OPT_NO_DEBUGGER_THROW_NOTIFY
#CCOPTS_FEATURES += -DDUK_OPT_DEBUGGER_PAUSE_UNCAUGHT
#CCOPTS_FEATURES += -DDUK_OPT_DEBUGGER_TRANSPORT_TORTURE
CCOPTS_FEATURES += -DDUK_OPT_TARGET_INFO='"duk command built from Duktape repo"'
#CCOPTS_FEATURES += -DDUK_OPT_NO_JX
#CCOPTS_FEATURES += -DDUK_OPT_NO_JC
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_FUNC_STMT
#CCOPTS_FEATURES += -DDUK_OPT_NONSTD_FUNC_CALLER_PROPERTY
#CCOPTS_FEATURES += -DDUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029
#CCOPTS_FEATURES += -DDUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT
#CCOPTS_FEATURES += -DDUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY
#CCOPTS_FEATURES += -DDUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF
#CCOPTS_FEATURES += -DDUK_OPT_NO_ES6_PROXY
#CCOPTS_FEATURES += -DDUK_OPT_NO_ZERO_BUFFER_DATA
#CCOPTS_FEATURES += -DDUK_OPT_USER_INITJS='"this.foo = 123"'
#CCOPTS_FEATURES += -DDUK_OPT_SETJMP
#CCOPTS_FEATURES += -DDUK_OPT_UNDERSCORE_SETJMP
#CCOPTS_FEATURES += -DDUK_OPT_SIGSETJMP
#CCOPTS_FEATURES += -DDUK_OPT_LIGHTFUNC_BUILTINS
CCOPTS_FEATURES += -DDUK_OPT_FASTINT
#CCOPTS_FEATURES += -DDUK_OPT_REFCOUNT16
#CCOPTS_FEATURES += -DDUK_OPT_STRHASH16
#CCOPTS_FEATURES += -DDUK_OPT_STRLEN16
#CCOPTS_FEATURES += -DDUK_OPT_BUFLEN16
#CCOPTS_FEATURES += -DDUK_OPT_OBJSIZES16
#CCOPTS_FEATURES += -DDUK_OPT_STRTAB_CHAIN
#CCOPTS_FEATURES += -DDUK_OPT_STRTAB_CHAIN_SIZE=128
#CCOPTS_FEATURES += -DDUK_OPT_HEAPPTR16
#CCOPTS_FEATURES += '-DDUK_OPT_HEAPPTR_ENC16(ud,p)=XXX'
#CCOPTS_FEATURES += '-DDUK_OPT_HEAPPTR_DEC16(ud,x)=XXX'
#CCOPTS_FEATURES += '-DDUK_OPT_DECLARE=XXX'
#CCOPTS_FEATURES += -DDUK_OPT_REGEXP_CANON_WORKAROUND
CCOPTS_FEATURES += -DDUK_OPT_JSON_STRINGIFY_FASTPATH
CCOPTS_FEATURES += -DDUK_CMDLINE_FANCY
CCOPTS_FEATURES += -DDUK_CMDLINE_ALLOC_LOGGING
CCOPTS_FEATURES += -DDUK_CMDLINE_ALLOC_TORTURE
CCOPTS_FEATURES += -DDUK_CMDLINE_ALLOC_HYBRID
CCOPTS_FEATURES += -DDUK_CMDLINE_DEBUGGER_SUPPORT

CCOPTS_SHARED =
CCOPTS_SHARED += -pedantic -ansi -std=c99 -fstrict-aliasing
# -Wextra is very picky but catches e.g. signed/unsigned comparisons
CCOPTS_SHARED += -Wall -Wextra -Wunused-result
CCOPTS_SHARED += -Wcast-qual
# -Wfloat-equal is too picky, there's no apparent way to compare floats
# (even when you know it's safe) without triggering warnings
CCOPTS_SHARED += -I./dist/src -I./dist/examples/alloc-logging -I./dist/examples/alloc-torture -I./dist/examples/alloc-hybrid -I./dist/examples/debug-trans-socket
#CCOPTS_SHARED += -I./dist/src-separate
#CCOPTS_SHARED += -m32                             # force 32-bit compilation on a 64-bit host
#CCOPTS_SHARED += -mx32                            # force X32 compilation on a 64-bit host

CCOPTS_NONDEBUG = $(CCOPTS_SHARED) $(CCOPTS_FEATURES)
CCOPTS_NONDEBUG += -Os -fomit-frame-pointer
CCOPTS_NONDEBUG += -g -ggdb
#CCOPTS_NONDEBUG += -DDUK_OPT_ASSERTIONS

CCOPTS_DEBUG = $(CCOPTS_SHARED) $(CCOPTS_FEATURES)
CCOPTS_DEBUG += -O0
CCOPTS_DEBUG += -g -ggdb
CCOPTS_DEBUG += -DDUK_OPT_DEBUG
CCOPTS_DEBUG += -DDUK_OPT_DPRINT
#CCOPTS_DEBUG += -DDUK_OPT_DDPRINT
#CCOPTS_DEBUG += -DDUK_OPT_DDDPRINT
CCOPTS_DEBUG += -DDUK_OPT_ASSERTIONS

GXXOPTS_NONDEBUG = -pedantic -ansi -std=c++11 -fstrict-aliasing -Wall -Wextra -Wunused-result -Os -fomit-frame-pointer
GXXOPTS_NONDEBUG += -I./dist/src -I./dist/examples/alloc-logging -I./dist/examples/alloc-torture -I./dist/examples/alloc-hybrid
GXXOPTS_NONDEBUG += -DDUK_OPT_DEBUGGER_SUPPORT -DDUK_OPT_INTERRUPT_COUNTER
GXXOPTS_DEBUG = -pedantic -ansi -std=c++11 -fstrict-aliasing -Wall -Wextra -Wunused-result -O0 -g -ggdb
GXXOPTS_DEBUG += -I./dist/src -I./dist/examples/alloc-logging -I./dist/examples/alloc-torture -I./dist/examples/alloc-hybrid
GXXOPTS_DEBUG += -DDUK_OPT_DEBUG -DDUK_OPT_DPRINT -DDUK_OPT_ASSERTIONS -DDUK_OPT_SELF_TESTS
#GXXOPTS_DEBUG += -DDUK_OPT_DDPRINT -DDUK_OPT_DDDPRINT

CCLIBS	= -lm
CCLIBS += -lreadline
CCLIBS += -lncurses  # on some systems -lreadline also requires -lncurses (e.g. RHEL)

# Replace 'duk' and 'dukd' with automatic valgrind wrappers (plain commands
# will be duk.raw and dukd.raw).  Targets for runtests.js bypass the wrapper
# because runtests.js has its own valgrind handling.
#VALGRIND_WRAP=1

# Compile 'duk' only by default
.PHONY:	all
all:	checksetup duk

.PHONY: checksetup
checksetup:
	@util/check_setup.sh

.PHONY:	clean
clean:
	@rm -rf dist/
	@rm -rf site/
	@rm -f duk.raw dukd.raw duk.vg dukd.vg duk dukd duk.O2 duk.O3 duk.O4
	@rm -f duk-g++ dukd-g++
	@rm -f duk-clang
	@rm -f ajduk ajdukd
	@rm -f emduk emduk.js
	@rm -f libduktape*.so*
	@rm -f duktape-*.tar.*
	@rm -f duktape-*.iso
	@rm -f doc/*.html
	@rm -f src/*.pyc
	@rm -rf massif.out.* ms_print.tmp.*
	@rm -rf cachegrind.out.*
	@rm -rf callgrind.out.*
	@rm -rf oprofile_data/
	@rm -f /tmp/duk_sizes.html
	@rm -f /tmp/duk-test-eval-file-temp.js  # used by tests/api/test-eval-file.js
	@rm -rf /tmp/duktape-regfuzz/
	@rm -f /tmp/duk-test.log /tmp/duk-api-test.log
	@rm -f /tmp/duk-test262.log /tmp/duk-test262-filtered.log
	@rm -f /tmp/duk-emcc-test*
	@rm -f /tmp/duk-emcc-luatest*
	@rm -f /tmp/duk-emcc-duktest*
	@rm -f /tmp/duk-jsint-test*
	@rm -f /tmp/duk-luajs-mandel.js /tmp/duk-luajs-test.js
	@rm -f /tmp/duk-closure-test*
	@rm -f /tmp/duk-bluebird-test*
	@rm -f a.out
	@rm -rf test262-*
	@rm -rf lua-5.2.3
	@rm -rf luajs
	@rm -f dukweb.js
	@rm -rf /tmp/dukweb-test/
	@rm -f massif-*.out

.PHONY: cleanall
cleanall: clean
	# Don't delete these in 'clean' to avoid re-downloading them over and over
	@rm -rf duktape-releases
	@rm -f regfuzz-*.tar.gz
	@rm -rf UglifyJS
	@rm -rf UglifyJS2
	@rm -rf closure-compiler
	@rm -rf underscore
	@rm -rf lodash
	@rm -f d067d2f0ca30.tar.bz2
	@rm -rf emscripten
	@rm -rf JS-Interpreter
	@rm -f compiler-latest.zip
	@rm -f compiler.jar
	@rm -f cloc-1.60.pl
	@rm -f lua-5.2.3.tar.gz
	@rm -f luajs.zip
	@rm -f bluebird.js
	@rm -f jquery-1.11.0.js
	@rm -rf coffee-script
	@rm -rf LiveScript
	@rm -rf coco
	@rm -rf sax-js
	@rm -rf xmldoc
	@rm -rf FlameGraph
	@rm -rf dtrace4linux
	@rm -rf flow
	@rm -rf 3883a2e9063b0a5f2705bdac3263577a03913c94.zip
	@rm -rf es5-tests.zip
	@rm -rf alljoyn-js ajtcl
	@rm -f v1.3.5.tar.gz

libduktape.so.1.0.0: dist
	rm -f $(subst .so.1.0.0,.so.1,$@) $(subst .so.1.0.0,.so.1.0.0,$@) $(subst .so.1.0.0,.so,$@)
	$(CC) -o $@ -shared -Wl,-soname,$(subst .so.1.0.0,.so.1,$@) -fPIC $(CCOPTS_NONDEBUG) $(DUKTAPE_SOURCES) $(CCLIBS)
	ln -s $@ $(subst .so.1.0.0,.so.1,$@)
	ln -s $@ $(subst .so.1.0.0,.so,$@)

libduktaped.so.1.0.0: dist
	rm -f $(subst .so.1.0.0,.so.1,$@) $(subst .so.1.0.0,.so.1.0.0,$@) $(subst .so.1.0.0,.so,$@)
	$(CC) -o $@ -shared -Wl,-soname,$(subst .so.1.0.0,.so.1,$@) -fPIC $(CCOPTS_DEBUG) $(DUKTAPE_SOURCES) $(CCLIBS)
	ln -s $@ $(subst .so.1.0.0,.so.1,$@)
	ln -s $@ $(subst .so.1.0.0,.so,$@)

duk.raw: dist
	$(CC) -o $@ $(CCOPTS_NONDEBUG) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

duk-clang: dist
	# Use -Wcast-align to trigger issues like: https://github.com/svaarala/duktape/issues/270
	clang -o $@ -Wcast-align $(CCOPTS_NONDEBUG) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

duk.O2: dist
	$(CC) -o $@ $(CCOPTS_NONDEBUG) -O2 $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

duk.O3: dist
	$(CC) -o $@ $(CCOPTS_NONDEBUG) -O3 $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

duk.O4: dist
	$(CC) -o $@ $(CCOPTS_NONDEBUG) -O4 $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

# Test target for g++ compile
duk-g++: dist
	$(GXX) -o $@ $(GXXOPTS_NONDEBUG) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@
dukd-g++: dist
	$(GXX) -o $@ $(GXXOPTS_DEBUG) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

dump-public: duk.raw
	@(objdump -t $< | grep ' g' | grep .text | grep -v .hidden | tr -s ' ' | cut -d ' ' -f 5 | sort > /tmp/duk-public.txt ; true)
	@echo "Symbol dump in /tmp/duk-public.txt"
	@(grep duk__ /tmp/duk-public.txt ; true)  # check for leaked file local symbols (does not cover internal, but not public symbols)

duk.vg: duk.raw
	@rm -f $@
	@echo '#!/bin/sh' > $@
	@echo 'valgrind "$(shell pwd)/$<" "$$@"' >> $@
	@chmod ugo+rx $@

duk: duk.raw duk.vg
	@rm -f $@
ifeq ($(VALGRIND_WRAP),1)
	@echo "Using valgrind wrapped $@"
	@cp duk.vg $@
else
	@cp duk.raw $@
endif

dukd.raw: dist
	$(CC) -o $@ $(CCOPTS_DEBUG) $(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)
	-@size $@

dukd.vg: dukd.raw
	@rm -f $@
	@echo '#!/bin/sh' > $@
	@echo 'valgrind "$(shell pwd)/$<" "$$@"' >> $@
	@chmod ugo+rx $@

dukd: dukd.raw dukd.vg
	@rm -f dukd
ifeq ($(VALGRIND_WRAP),1)
	@echo "Using valgrind wrapped $@"
	@cp dukd.vg $@
else
	@cp dukd.raw $@
endif

.PHONY: duksizes
duksizes: duk.raw
	$(PYTHON) src/genexesizereport.py $< > /tmp/duk_sizes.html

.PHONY: issuecount
issuecount:
	@echo "FIXME:     `grep FIXME: src/*.c src/*.h src/*.in | wc -l | tr -d ' '`"
	@echo "XXX:       `grep XXX: src/*.c src/*.h src/*.in | wc -l | tr -d ' '`"
	@echo "TODO:      `grep TODO: src/*.c src/*.h src/*.in | wc -l | tr -d ' '`"
	@echo "NOTE:      `grep NOTE: src/*.c src/*.h src/*.in | wc -l | tr -d ' '`"
	@echo "SCANBUILD: `grep SCANBUILD: src/*.c src/*.h src/*.in | wc -l | tr -d ' '`"

.PHONY: dukscanbuild
dukscanbuild: dist
	scan-build gcc -o/tmp/duk.scanbuild -Idist/src-separate/ $(CCOPTS_NONDEBUG) $(DUKTAPE_SOURCES_SEPARATE) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)

.PHONY: dukdscanbuild
dukdscanbuild: dist
	scan-build gcc -o/tmp/duk.scanbuild -Idist/src-separate/ $(CCOPTS_DEBUG) $(DUKTAPE_SOURCES_SEPARATE) $(DUKTAPE_CMDLINE_SOURCES) $(CCLIBS)

.PHONY: test
test: qecmatest apitest regfuzztest underscoretest lodashtest emscriptentest emscripteninceptiontest test262test

RUNTESTSOPTS=--prep-test-path util/prep_test.py --minify-uglifyjs2 UglifyJS2/bin/uglifyjs --util-include-path tests/ecmascript --known-issues doc/testcase-known-issues.yaml

.PHONY:	ecmatest
ecmatest: runtestsdeps duk
ifeq ($(VALGRIND_WRAP),1)
	@echo "### ecmatest (valgrind)"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/duk.raw --report-diff-to-other --valgrind --run-nodejs --run-rhino --num-threads 1 --log-file=/tmp/duk-test.log tests/ecmascript/
else
	@echo "### ecmatest"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/duk --report-diff-to-other --run-nodejs --run-rhino --num-threads 4 --log-file=/tmp/duk-test.log tests/ecmascript/
endif

.PHONY:	ecmatestd
ecmatestd: runtestsdeps dukd
ifeq ($(VALGRIND_WRAP),1)
	@echo "### ecmatestd (valgrind)"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/dukd.raw --report-diff-to-other --valgrind --run-nodejs --run-rhino --num-threads 1 --log-file=/tmp/duk-test.log tests/ecmascript/
else
	@echo "### ecmatestd"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/dukd --report-diff-to-other --run-nodejs --run-rhino --num-threads 4 --log-file=/tmp/duk-test.log tests/ecmascript/
endif

.PHONY:	qecmatest
qecmatest: runtestsdeps duk
ifeq ($(VALGRIND_WRAP),1)
	@echo "### qecmatest (valgrind)"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/duk.raw --valgrind --num-threads 1 --log-file=/tmp/duk-test.log tests/ecmascript/
else
	@echo "### qecmatest"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/duk --num-threads 4  --log-file=/tmp/duk-test.log tests/ecmascript/
endif

.PHONY:	qecmatestd
qecmatestd: runtestsdeps dukd
ifeq ($(VALGRIND_WRAP),1)
	@echo "### qecmatestd (valgrind)"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/dukd.raw --valgrind --num-threads 1 --log-file=/tmp/duk-test.log tests/ecmascript/
else
	@echo "### qecmatestd"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --run-duk --cmd-duk=$(shell pwd)/dukd --num-threads 4 --log-file=/tmp/duk-test.log tests/ecmascript/
endif

# Separate target because it's also convenient to run manually.
.PHONY: apiprep
apiprep: runtestsdeps libduktape.so.1.0.0

.PHONY:	apitest
apitest: apiprep
ifeq ($(VALGRIND_WRAP),1)
	@echo "### apitest (valgrind)"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --num-threads 1 --valgrind --log-file=/tmp/duk-api-test.log tests/api/
else
	@echo "### apitest"
	"$(NODE)" runtests/runtests.js $(RUNTESTSOPTS) --num-threads 1 --log-file=/tmp/duk-api-test.log tests/api/
endif

.PHONY: matrix10
matrix10: dist
	cd dist; python ../util/matrix_compile.py --count=10
.PHONY: matrix100
matrix100: dist
	cd dist; python ../util/matrix_compile.py --count=100
.PHONY: matrix1000
matrix1000: dist
	cd dist; python ../util/matrix_compile.py --count=1000
.PHONY: matrix10000
matrix10000: dist
	cd dist; python ../util/matrix_compile.py --count=10000

regfuzz-0.1.tar.gz:
	# https://code.google.com/p/regfuzz/
	# SHA1: 774be8e3dda75d095225ba699ac59969d92ac970
	$(WGET) https://regfuzz.googlecode.com/files/regfuzz-0.1.tar.gz -O $@

.PHONY:	regfuzztest
regfuzztest: regfuzz-0.1.tar.gz duk
	@echo "### regfuzztest"
	# Spidermonkey test is pretty close, just lacks 'arguments'
	# Should run with assertions enabled in 'duk'
	rm -rf /tmp/duktape-regfuzz; mkdir -p /tmp/duktape-regfuzz
	cp regfuzz-0.1.tar.gz duk /tmp/duktape-regfuzz
	tar -C /tmp/duktape-regfuzz -x -v -z -f regfuzz-0.1.tar.gz
	echo "arguments = [ 0xdeadbeef ];" > /tmp/duktape-regfuzz/regfuzz-test.js
	cat /tmp/duktape-regfuzz/regfuzz-0.1/examples/spidermonkey/regexfuzz.js >> /tmp/duktape-regfuzz/regfuzz-test.js
	cd /tmp/duktape-regfuzz; ./duk regfuzz-test.js

underscore:
	# http://underscorejs.org/
	# https://github.com/jashkenas/underscore
	# Master is OK because not a critical dependency
	$(GIT) clone --depth 1 https://github.com/jashkenas/underscore.git

.PHONY: underscoretest
underscoretest:	underscore duk
	@echo "### underscoretest"
	@echo "Run underscore tests with underscore-test-shim.js"
	-util/underscore_test.sh ./duk underscore/test/arrays.js
	-util/underscore_test.sh ./duk underscore/test/chaining.js
	-util/underscore_test.sh ./duk underscore/test/collections.js
	-util/underscore_test.sh ./duk underscore/test/functions.js
	-util/underscore_test.sh ./duk underscore/test/objects.js
	# speed test disabled, requires JSLitmus
	#-util/underscore_test.sh ./duk underscore/test/speed.js
	-util/underscore_test.sh ./duk underscore/test/utility.js

lodash:
	# http://lodash.com/
	# https://github.com/lodash
	# Master is OK because not a critical dependency
	$(GIT) clone --depth 1 https://github.com/lodash/lodash.git

# Lodash test.js assumes require() etc.  Placeholder test for now, no
# expect string etc.
.PHONY: lodashtest
lodashtest: lodash duk
	./duk lodash/lodash.js tests/lodash/basic.js

3883a2e9063b0a5f2705bdac3263577a03913c94.zip:
	# http://test262.ecmascript.org/
	# https://github.com/tc39/test262
	# HG repo seems to have migrated to https://github.com/tc39/test262
	#$(WGET) http://hg.ecmascript.org/tests/test262/archive/d067d2f0ca30.tar.bz2 -O $@
	#$(WGET) https://github.com/tc39/test262/archive/595a36b252ee97110724e6fa89fc92c9aa9a206a.zip -O $@
	# This is a snapshot from the master, and seems to have test case bugs
	$(WGET) https://github.com/tc39/test262/archive/3883a2e9063b0a5f2705bdac3263577a03913c94.zip -O $@
test262-3883a2e9063b0a5f2705bdac3263577a03913c94: 3883a2e9063b0a5f2705bdac3263577a03913c94.zip
	unzip $<
	touch $@

es5-tests.zip:
	# https://github.com/tc39/test262/tree/es5-tests
	# This is a stable branch for ES5 tests
	$(WGET) https://github.com/tc39/test262/archive/es5-tests.zip -O $@
test262-es5-tests: es5-tests.zip
	unzip $<
	touch $@

.PHONY: test262test
test262test: test262-es5-tests duk
	@echo "### test262test"
	# http://wiki.ecmascript.org/doku.php?id=test262:command
	rm -f /tmp/duk-test262.log /tmp/duk-test262-filtered.log
	-cd $<; $(PYTHON) tools/packaging/test262.py --command "../duk {{path}}" --summary >/tmp/duk-test262.log
	cat /tmp/duk-test262.log | $(PYTHON) util/filter_test262_log.py doc/test262-known-issues.yaml > /tmp/duk-test262-filtered.log
	cat /tmp/duk-test262-filtered.log

# Unholy helper to write out a testcase, the unholiness is that it reads
# command line arguments and complains about missing targets etc:
# http://stackoverflow.com/questions/6273608/how-to-pass-argument-to-makefile-from-command-line
.PHONY: test262cat
test262cat: test262-es5-tests
	@echo "NOTE: this Makefile target will print a 'No rule...' error, ignore it" >&2
	-@cd $<; $(PYTHON) tools/packaging/test262.py --command "../duk {{path}}" --cat $(filter-out $@,$(MAKECMDGOALS))

emscripten:
	# https://github.com/kripken/emscripten
	# Master is OK because not a critical dependency
	# Setup is complicated because needs matching fastcomp which
	# you must provide yourself and add to ~/.emscripten:
	# http://kripken.github.io/emscripten-site/docs/building_from_source/building_fastcomp_manually_from_source.html
	$(GIT) clone --depth 1 https://github.com/kripken/emscripten.git
	cd emscripten; ./emconfigure

# Reducing the TOTAL_MEMORY and TOTAL_STACK values is useful if you run
# Duktape cmdline with resource limits (i.e. "duk -r test.js").
#EMCCOPTS=-s TOTAL_MEMORY=2097152 -s TOTAL_STACK=524288 --memory-init-file 0
EMCCOPTS=-O2 -std=c99 -Wall --memory-init-file 0

EMDUKOPTS=-s TOTAL_MEMORY=268435456 -DDUK_OPT_NO_FASTINT -DDUK_OPT_NO_PACKED_TVAL
EMDUKOPTS+=-DEMSCRIPTEN  # enable stdin workaround in duk_cmdline.c
emduk: emduk.js
	cat util/emduk_wrapper.sh | sed "s|WORKDIR|$(shell pwd)|" > $@
	chmod ugo+x $@

# util/fix_emscripten.py is used so that emduk.js can also be executed using
# Duktape itself (though you can't currently pass arguments/files to it).
emduk.js: dist emscripten
	emscripten/emcc $(EMCCOPTS) -Idist/src -Idist/examples/cmdline \
		$(EMDUKOPTS) \
		dist/src/duktape.c dist/examples/cmdline/duk_cmdline.c \
		-o /tmp/duk-emduk.js
	cat /tmp/duk-emduk.js | $(PYTHON) util/fix_emscripten.py > $@
	@ls -l $@

.PHONY: emscriptentest
emscriptentest: emscripten duk
	@echo "### emscriptentest"
	@rm -f /tmp/duk-emcc-test*
	@echo "NOTE: this emscripten test is incomplete (compiles helloworld.c and tries to run it, no checks yet)"
	emscripten/emcc $(EMCCOPTS) tests/emscripten/helloworld.c -o /tmp/duk-emcc-test.js
	cat /tmp/duk-emcc-test.js | $(PYTHON) util/fix_emscripten.py > /tmp/duk-emcc-test-fixed.js
	@ls -l /tmp/duk-emcc-test*
	./duk /tmp/duk-emcc-test-fixed.js
	#./duk /tmp/duk-emcc-test.js

.PHONY: emscriptenmandeltest
emscriptenmandeltest: emscripten duk
	@echo "### emscriptenmandeltest"
	@rm -f /tmp/duk-emcc-test*
	@echo "NOTE: this emscripten test is incomplete (compiles mandelbrot.c and tries to run it, no checks yet)"
	emscripten/emcc $(EMCCOPTS) tests/emscripten/mandelbrot.c -o /tmp/duk-emcc-test.js
	cat /tmp/duk-emcc-test.js | $(PYTHON) util/fix_emscripten.py > /tmp/duk-emcc-test-fixed.js
	@ls -l /tmp/duk-emcc-test*
	./duk /tmp/duk-emcc-test-fixed.js
	#./duk /tmp/duk-emcc-test.js

# Compile Duktape and hello.c using Emscripten and execute the result with
# Duktape.
.PHONY: emscripteninceptiontest
emscripteninceptiontest: emscripten dist duk
	@echo "### emscripteniceptiontest"
	@rm -f /tmp/duk-emcc-test*
	@echo "NOTE: this emscripten test is incomplete (compiles Duktape and hello.c and tries to run it, no checks yet)"
	emscripten/emcc $(EMCCOPTS) -Idist/src dist/src/duktape.c dist/examples/hello/hello.c -o /tmp/duk-emcc-test.js
	cat /tmp/duk-emcc-test.js | $(PYTHON) util/fix_emscripten.py > /tmp/duk-emcc-test-fixed.js
	@ls -l /tmp/duk-emcc-test*
	./duk /tmp/duk-emcc-test-fixed.js
	#./duk /tmp/duk-emcc-test.js

# Compile Duktape with Emscripten and execute it with NodeJS:
#   - --memory-init-file 0 to avoid a separate memory init file (this is
#     not mandatory but keeps the result in a single file)
#   - -DEMSCRIPTEN needed by Duktape for feature detection
# https://github.com/kripken/emscripten/wiki/Optimizing-Code
# http://mozakai.blogspot.fi/2013/08/outlining-workaround-for-jits-and-big.html
EMCCOPTS_DUKVM=-O2 -std=c99 -Wall --memory-init-file 0 -DEMSCRIPTEN

MAND_BASE64=dyA9IDgwOyBoID0gNDA7IGl0ZXIgPSAxMDA7IGZvciAoaSA9IDA7IGkgLSBoOyBpICs9IDEpIHsgeTAgPSAoaSAvIGgpICogNC4wIC0gMi4wOyByZXMgPSBbXTsgZm9yIChqID0gMDsgaiAtIHc7IGogKz0gMSkgeyB4MCA9IChqIC8gdykgKiA0LjAgLSAyLjA7IHh4ID0gMDsgeXkgPSAwOyBjID0gIiMiOyBmb3IgKGsgPSAwOyBrIC0gaXRlcjsgayArPSAxKSB7IHh4MiA9IHh4Knh4OyB5eTIgPSB5eSp5eTsgaWYgKE1hdGgubWF4KDAsIDQuMCAtICh4eDIgKyB5eTIpKSkgeyB5eSA9IDIqeHgqeXkgKyB5MDsgeHggPSB4eDIgLSB5eTIgKyB4MDsgfSBlbHNlIHsgYyA9ICIuIjsgYnJlYWs7IH0gfSByZXNbcmVzLmxlbmd0aF0gPSBjOyB9IHByaW50KHJlcy5qb2luKCIiKSk7IH0K

.PHONY: emscriptenduktest
emscriptenduktest: emscripten dist
	@echo "### emscriptenduktest"
	@rm -f /tmp/duk-emcc-duktest.js
	emscripten/emcc $(EMCCOPTS_DUKVM) -DDUK_OPT_ASSERTIONS -DDUK_OPT_SELF_TESTS -Idist/src/ dist/src/duktape.c dist/examples/eval/eval.c -o /tmp/duk-emcc-duktest.js
	"$(NODE)" /tmp/duk-emcc-duktest.js \
		'print("Hello from Duktape running inside Emscripten/NodeJS");' \
		'print(Duktape.version, Duktape.env);' \
		'for(i=0;i++<100;)print((i%3?"":"Fizz")+(i%5?"":"Buzz")||i)'
	"$(NODE)" /tmp/duk-emcc-duktest.js "eval(''+Duktape.dec('base64', '$(MAND_BASE64)'))"

# This is a prototype of running Duktape in a web environment with Emscripten,
# and providing an eval() facility from both sides.  This is a placeholder now
# and doesn't do anything useful yet.
EMCCOPTS_DUKWEB_EXPORT=-s EXPORTED_FUNCTIONS='["_dukweb_is_open", "_dukweb_open","_dukweb_close","_dukweb_eval"]'
EMCCOPTS_DUKWEB_DEFINES='-DDUK_OPT_DECLARE=extern void dukweb_panic_handler(int code, const char *msg);' '-DDUK_OPT_PANIC_HANDLER(code,msg)={dukweb_panic_handler((code),(msg));abort();}'
#EMCCOPTS_DUKWEB_DEFINES+=-DDUK_OPT_ASSERTIONS
EMCCOPTS_DUKWEB_DEFINES+=-DDUK_OPT_SELF_TESTS

dukweb.js: emscripten dist
	emscripten/emcc $(EMCCOPTS_DUKVM) $(EMCCOPTS_DUKWEB_EXPORT) $(EMCCOPTS_DUKWEB_DEFINES) \
		-Idist/src/ dist/src/duktape.c dukweb/dukweb.c -o dukweb.js
	cat dukweb/dukweb_extra.js >> dukweb.js
	@wc dukweb.js

.PHONY: dukwebtest
dukwebtest: dukweb.js jquery-1.11.0.js
	@echo "### dukwebtest"
	@rm -rf /tmp/dukweb-test/
	mkdir /tmp/dukweb-test/
	cp dukweb.js jquery-1.11.0.js dukweb/dukweb.html dukweb/dukweb.css /tmp/dukweb-test/
	@echo "Now point your browser to: file:///tmp/dukweb-test/dukweb.html"

jquery-1.11.0.js:
	$(WGET) http://code.jquery.com/jquery-1.11.0.js -O $@

lua-5.2.3.tar.gz:
	$(WGET) http://www.lua.org/ftp/lua-5.2.3.tar.gz -O $@

lua-5.2.3: lua-5.2.3.tar.gz
	tar xfz lua-5.2.3.tar.gz

LUASRC=	lapi.c lauxlib.c lbaselib.c lbitlib.c lcode.c lcorolib.c lctype.c \
	ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c \
	llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c \
	lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c \
	lua.c lundump.c lvm.c lzio.c

# Compile Lua 5.2.3 with Emscripten and run it with Duktape.
.PHONY: emscriptenluatest
emscriptenluatest: emscripten duk lua-5.2.3
	@echo "### emscriptenluatest"
	@rm -f /tmp/duk-emcc-luatest*
	emscripten/emcc $(EMCCOPTS) -Ilua-5.2.3/src/ $(patsubst %,lua-5.2.3/src/%,$(LUASRC)) -o /tmp/duk-emcc-luatest.js
	cat /tmp/duk-emcc-luatest.js | $(PYTHON) util/fix_emscripten.py > /tmp/duk-emcc-luatest-fixed.js
	@ls -l /tmp/duk-emcc-luatest*
	./duk /tmp/duk-emcc-luatest-fixed.js

JS-Interpreter:
	# https://github.com/NeilFraser/JS-Interpreter
	# Master is OK because not a critical dependency
	$(GIT) clone --depth 1 https://github.com/NeilFraser/JS-Interpreter.git

.PHONY: jsinterpretertest
jsinterpretertest: JS-Interpreter duk
	@echo "### jsinterpretertest"
	@rm -f /tmp/duk-jsint-test*
	echo "window = {};" > /tmp/duk-jsint-test.js
	cat JS-Interpreter/acorn.js JS-Interpreter/interpreter.js >> /tmp/duk-jsint-test.js
	cat tests/jsinterpreter/addition.js >> /tmp/duk-jsint-test.js
	./duk /tmp/duk-jsint-test.js

luajs.zip:
	# https://github.com/mherkender/lua.js
	$(WGET) https://github.com/mherkender/lua.js/raw/precompiled2/luajs.zip -O $@

luajs: luajs.zip
	@rm -rf luajs/
	mkdir luajs
	cd luajs; unzip ../luajs.zip

.PHONY: luajstest
luajstest: luajs duk
	@rm -f /tmp/duk-luajs-mandel.js /tmp/duk-luajs-test.js
	luajs/lua2js tests/luajs/mandel.lua /tmp/duk-luajs-mandel.js
	echo "console = { log: function() { print(Array.prototype.join.call(arguments, ' ')); } };" > /tmp/duk-luajs-test.js
	cat luajs/lua.js /tmp/duk-luajs-mandel.js >> /tmp/duk-luajs-test.js
	./duk /tmp/duk-luajs-test.js

bluebird.js:
	$(WGET) https://cdn.jsdelivr.net/bluebird/latest/bluebird.js -O $@

.PHONY: bluebirdtest
bluebirdtest: bluebird.js duk
	@rm -f /tmp/duk-bluebird-test.js
	cat util/bluebird-test-shim.js bluebird.js > /tmp/duk-bluebird-test.js
	echo "var myPromise = new Promise(function(resolve, reject) { setTimeout(function () { resolve('resolved 123') }, 1000); });" >> /tmp/duk-bluebird-test.js
	echo "myPromise.then(function (v) { print('then:', v); });" >> /tmp/duk-bluebird-test.js
	echo "fakeEventLoop();" >> /tmp/duk-bluebird-test.js
	./duk /tmp/duk-bluebird-test.js

# Closure
compiler-latest.zip:
	# Prebuilt latest version; this is not good as a build dependency
	# because closure changes may break minified initjs code and make
	# old builds unreliable.
	# https://code.google.com/p/closure-compiler/
	$(WGET) http://dl.google.com/closure-compiler/compiler-latest.zip -O $@

closure-compiler:
	# https://github.com/google/closure-compiler
	@rm -f v20140814.tar.gz
	$(WGET) https://github.com/google/closure-compiler/archive/v20140814.tar.gz -O v20140814.tar.gz
	tar xfz v20140814.tar.gz
	mv closure-compiler-20140814 closure-compiler
	@rm -f v20140814.tar.gz

closure-compiler/build/compiler.jar: closure-compiler
	cd closure-compiler; ant

compiler.jar: closure-compiler/build/compiler.jar
	cp closure-compiler/build/compiler.jar $@
	touch $@  # ensure date is newer than compiler-latest.zip

.PHONY: closuretest
closuretest: compiler.jar duk
	@echo "### closuretest"
	@rm -f /tmp/duk-closure-test*
	$(JAVA) -jar compiler.jar tests/ecmascript/test-dev-mandel2-func.js > /tmp/duk-closure-test.js
	./duk /tmp/duk-closure-test.js

UglifyJS:
	# https://github.com/mishoo/UglifyJS
	# Use a specific release because UglifyJS is used in building Duktape
	@rm -f v1.3.5.tar.gz
	$(WGET) https://github.com/mishoo/UglifyJS/archive/v1.3.5.tar.gz -O v1.3.5.tar.gz
	tar xfz v1.3.5.tar.gz
	mv UglifyJS-1.3.5 UglifyJS
	@rm -f v1.3.5.tar.gz

	# Don't use this because it's a moving critical dependency
	#$(GIT) clone --depth 1 https://github.com/mishoo/UglifyJS.git

UglifyJS2:
	# https://github.com/mishoo/UglifyJS2
	# Use a specific release because UglifyJS2 is used in building Duktape
	# (This is now a bit futile because UglifyJS2 requires an 'npm install',
	# the NodeJS dependencies need to be controlled for this to really work.)
	@rm -f v2.4.12.tar.gz
	$(WGET) https://github.com/mishoo/UglifyJS2/archive/v2.4.12.tar.gz -O v2.4.12.tar.gz
	tar xfz v2.4.12.tar.gz
	mv UglifyJS2-2.4.12 UglifyJS2
	@rm -f v2.4.12.tar.gz

	# Don't use this because it's a moving critical dependency
	#$(GIT) clone --depth 1 https://github.com/mishoo/UglifyJS2.git

	cd UglifyJS2; npm install; cd -

cloc-1.60.pl:
	# http://cloc.sourceforge.net/
	$(WGET) http://downloads.sourceforge.net/project/cloc/cloc/v1.60/cloc-1.60.pl -O $@

coffee-script:
	# http://coffeescript.org/
	# https://github.com/jashkenas/coffee-script
	$(GIT) clone --depth 1 https://github.com/jashkenas/coffee-script.git

LiveScript:
	# http://livescript.net/
	# https://github.com/gkz/LiveScript
	$(GIT) clone --depth 1 https://github.com/gkz/LiveScript.git

coco:
	# https://github.com/satyr/coco
	$(GIT) clone --depth 1 https://github.com/satyr/coco

sax-js:
	# https://github.com/isaacs/sax-js
	$(GIT) clone --depth 1 https://github.com/isaacs/sax-js.git

xmldoc:
	# https://github.com/nfarina/xmldoc
	# http://nfarina.com/post/34302964969/a-lightweight-xml-document-class-for-nodejs-javascript
	$(GIT) clone --depth 1 https://github.com/nfarina/xmldoc.git

xmldoctest: sax-js xmldoc duk
	@echo "### xmldoctest"
	@rm -f /tmp/duk-xmldoc-test*
	cat sax-js/lib/sax.js > /tmp/duk-xmldoc-test.js
	echo ";" >> /tmp/duk-xmldoc-test.js  # missing end semicolon causes automatic semicolon problem
	cat xmldoc/lib/xmldoc.js >> /tmp/duk-xmldoc-test.js
	echo ";" >> /tmp/duk-xmldoc-test.js  # missing end semicolon causes automatic semicolon problem
	cat tests/xmldoc/basic.js >> /tmp/duk-xmldoc-test.js
	./duk /tmp/duk-xmldoc-test.js

FlameGraph:
	# http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html
	# https://github.com/brendangregg/FlameGraph
	$(GIT) clone --depth 1 https://github.com/brendangregg/FlameGraph.git

dtrace4linux:
	# https://github.com/dtrace4linux/linux
	# http://crtags.blogspot.fi/
	$(GIT) clone --depth 1 https://github.com/dtrace4linux/linux.git dtrace4linux

flow:
	# https://github.com/facebook/flow
	$(GIT) clone --depth 1 https://github.com/facebook/flow.git

alljoyn-js:
	# https://git.allseenalliance.org/cgit/core/alljoyn-js.git/
	# no --depth 1 ("dumb http transport does not support --depth")
	$(GIT) clone https://git.allseenalliance.org/gerrit/core/alljoyn-js.git

ajtcl:
	# https://git.allseenalliance.org/cgit/core/ajtcl.git/
	# no --depth 1 ("dumb http transport does not support --depth")
	$(GIT) clone https://git.allseenalliance.org/gerrit/core/ajtcl.git/
	ln -s . ajtcl/inc/ajtcl  # workaround for #include <ajtcl/xxx.h>
	ln -s . ajtcl/src/target/linux/ajtcl

CCOPTS_AJDUK = -m32
#CCOPTS_AJDUK += '-fpack-struct=1'
CCOPTS_AJDUK += -Wno-unused-parameter -Wno-pedantic -Wno-sign-compare -Wno-missing-field-initializers -Wno-unused-result
CCOPTS_AJDUK += -UDUK_CMDLINE_FANCY -DDUK_CMDLINE_AJSHEAP -D_POSIX_C_SOURCE=200809L
CCOPTS_AJDUK += -DDUK_OPT_FORCE_ALIGN=4
CCOPTS_AJDUK += -DDUK_OPT_ASSERTIONS
CCOPTS_AJDUK += -DDUK_OPT_LIGHTFUNC_BUILTINS
CCOPTS_AJDUK += -DDUK_OPT_REFCOUNT16
CCOPTS_AJDUK += -DDUK_OPT_STRHASH16
CCOPTS_AJDUK += -DDUK_OPT_STRLEN16
CCOPTS_AJDUK += -DDUK_OPT_BUFLEN16
CCOPTS_AJDUK += -DDUK_OPT_OBJSIZES16
CCOPTS_AJDUK += -DDUK_OPT_STRTAB_CHAIN
CCOPTS_AJDUK += -DDUK_OPT_STRTAB_CHAIN_SIZE=128
CCOPTS_AJDUK += -DDUK_OPT_HEAPPTR16
CCOPTS_AJDUK += '-DDUK_OPT_HEAPPTR_ENC16(ud,p)=ajsheap_enc16((ud),(p))'
CCOPTS_AJDUK += '-DDUK_OPT_HEAPPTR_DEC16(ud,x)=ajsheap_dec16((ud),(x))'
CCOPTS_AJDUK += -DDUK_OPT_EXTERNAL_STRINGS
#CCOPTS_AJDUK += '-DDUK_OPT_EXTSTR_INTERN_CHECK(ud,ptr,len)=ajsheap_extstr_check_1((ptr),(len))'
#CCOPTS_AJDUK += '-DDUK_OPT_EXTSTR_FREE(ud,ptr)=ajsheap_extstr_free_1((ptr))'
CCOPTS_AJDUK += '-DDUK_OPT_EXTSTR_INTERN_CHECK(ud,ptr,len)=ajsheap_extstr_check_2((ptr),(len))'
CCOPTS_AJDUK += '-DDUK_OPT_EXTSTR_FREE(ud,ptr)=ajsheap_extstr_free_2((ptr))'
#CCOPTS_AJDUK += '-DDUK_OPT_EXTSTR_INTERN_CHECK(ud,ptr,len)=ajsheap_extstr_check_3((ptr),(len))'
#CCOPTS_AJDUK += '-DDUK_OPT_EXTSTR_FREE(ud,ptr)=ajsheap_extstr_free_3((ptr))'
CCOPTS_AJDUK += '-DDUK_OPT_EXEC_TIMEOUT_CHECK(udata)=ajsheap_exec_timeout_check(udata)'
CCOPTS_AJDUK += '-DDUK_OPT_DECLARE=extern uint8_t *ajsheap_ram; extern duk_uint16_t ajsheap_enc16(void *ud, void *p); extern void *ajsheap_dec16(void *ud, duk_uint16_t x); extern const void *ajsheap_extstr_check_1(const void *ptr, duk_size_t len); extern const void *ajsheap_extstr_check_2(const void *ptr, duk_size_t len); extern const void *ajsheap_extstr_check_3(const void *ptr, duk_size_t len); extern void ajsheap_extstr_free_1(const void *ptr); extern void ajsheap_extstr_free_2(const void *ptr); extern void ajsheap_extstr_free_3(const void *ptr); extern duk_bool_t ajsheap_exec_timeout_check(void *udata);'
#CCOPTS_AJDUK += -DDUK_OPT_DEBUG -DDUK_OPT_DPRINT
#CCOPTS_AJDUK += -DDUK_OPT_DEBUG -DDUK_OPT_DPRINT -DDUK_OPT_DDPRINT -DDUK_OPT_DDDPRINT

# Command line with Alljoyn.js pool allocator, for low memory testing.
# The pool sizes only make sense with -m32, so force that.  This forces
# us to use barebones cmdline too.
ajduk: alljoyn-js ajtcl dist
	$(CC) -o $@ \
		-Ialljoyn-js/src -Iajtcl/inc/ -Iajtcl/src/target/linux/ \
		$(CCOPTS_NONDEBUG) \
		$(CCOPTS_AJDUK) \
		$(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) \
		dist/examples/cmdline/duk_cmdline_ajduk.c \
		alljoyn-js/src/ajs_heap.c ajtcl/src/aj_debug.c ajtcl/src/target/linux/aj_target_util.c \
		-lm -lpthread
	@echo "*** SUCCESS:"
	@ls -l ajduk
ajdukd: alljoyn-js ajtcl dist
	$(CC) -o $@ \
		-Ialljoyn-js/src -Iajtcl/inc/ -Iajtcl/src/target/linux/ \
		$(CCOPTS_DEBUG) \
		$(CCOPTS_AJDUK) \
		$(DUKTAPE_SOURCES) $(DUKTAPE_CMDLINE_SOURCES) \
		dist/examples/cmdline/duk_cmdline_ajduk.c \
		alljoyn-js/src/ajs_heap.c ajtcl/src/aj_debug.c ajtcl/src/target/linux/aj_target_util.c \
		-lm -lpthread
	@echo "*** SUCCESS:"
	@ls -l ajdukd

.PHONY: gccpredefs
gccpredefs:
	gcc -dM -E - < /dev/null

.PHONY: clangpredefs
clangpredefs:
	clang -dM -E - < /dev/null

.PHONY:	runtestsdeps
runtestsdeps:	runtests/node_modules UglifyJS2

runtests/node_modules:
	echo "Installing required NodeJS modules for runtests"
	cd runtests; npm install

.PHONY:	doc
doc:	$(patsubst %.txt,%.html,$(wildcard doc/*.txt))

doc/%.html: doc/%.txt
	rst2html $< $@

cloc:	dist cloc-1.60.pl
	@echo "CLOC report on combined duktape.c source file"
	@perl cloc-1.60.pl --quiet dist/src/duktape.c

# Source distributable for end users
# XXX: want to run codepolicycheck when dist gets built, but don't want to depend on it.
# XXX: make prints a harmless warning related to the sub-make.
dist:
	@make codepolicycheck
	if [ -f compiler.jar ]; then sh util/make_dist.sh --minify closure --create-spdx; else sh util/make_dist.sh --minify none --create-spdx; fi

.PHONY:	dist-src
dist-src:	dist
	rm -rf duktape-$(DUK_VERSION_FORMATTED)
	rm -rf duktape-$(DUK_VERSION_FORMATTED).tar*
	mkdir duktape-$(DUK_VERSION_FORMATTED)
	cp -r dist/* duktape-$(DUK_VERSION_FORMATTED)/
	tar cvfz duktape-$(DUK_VERSION_FORMATTED).tar.gz duktape-$(DUK_VERSION_FORMATTED)/
	tar cvf duktape-$(DUK_VERSION_FORMATTED).tar duktape-$(DUK_VERSION_FORMATTED)/
	xz -z -e -9 duktape-$(DUK_VERSION_FORMATTED).tar
	cp duktape-$(DUK_VERSION_FORMATTED).tar.gz duktape-$(DUK_VERSION_FORMATTED)-$(BUILD_DATETIME)-$(GIT_INFO).tar.gz
	cp duktape-$(DUK_VERSION_FORMATTED).tar.xz duktape-$(DUK_VERSION_FORMATTED)-$(BUILD_DATETIME)-$(GIT_INFO).tar.xz
	rm -rf duktape-$(DUK_VERSION_FORMATTED)

# Require closure compiler for official build
.PHONY: dist-src-official
dist-src-official:	compiler.jar dist-src

# ISO target is useful with some system emulators with no network access
.PHONY: dist-iso
dist-iso:	dist-src
	mkisofs -input-charset utf-8 -o duktape-$(DUK_VERSION_FORMATTED)-$(BUILD_DATETIME)-$(GIT_INFO).iso duktape-$(DUK_VERSION_FORMATTED)-$(BUILD_DATETIME)-$(GIT_INFO).tar.gz

.PHONY: tidy-site
tidy-site:
	for i in website/*/*.html; do echo "*** Checking $$i"; tidy -q -e -xml $$i; done

# Duktape binary releases are in a separate repo
duktape-releases:
	$(GIT) clone https://github.com/svaarala/duktape-releases.git

# Website
site: duktape-releases dukweb.js jquery-1.11.0.js
	rm -rf site
	mkdir site
	-cd duktape-releases/; git pull --rebase  # get binaries up-to-date, but allow errors for offline use
	cd website/; $(PYTHON) buildsite.py ../site/
	@rm -rf /tmp/site/
	cp -r site /tmp/  # useful for quick preview

.PHONY:	dist-site
dist-site:	tidy-site site
	# When doing a final dist build, run html tidy
	# Also pull binaries up-to-date
	cd duktape-releases/; git pull --rebase  # get binaries up-to-date
	rm -rf duktape-site-$(DUK_VERSION_FORMATTED)
	rm -rf duktape-site-$(DUK_VERSION_FORMATTED).tar*
	mkdir duktape-site-$(DUK_VERSION_FORMATTED)
	cp -r site/* duktape-site-$(DUK_VERSION_FORMATTED)/
	tar cvf duktape-site-$(DUK_VERSION_FORMATTED).tar duktape-site-$(DUK_VERSION_FORMATTED)/
	xz -z -e -9 duktape-site-$(DUK_VERSION_FORMATTED).tar
	cp duktape-site-$(DUK_VERSION_FORMATTED).tar.xz duktape-site-$(DUK_VERSION_FORMATTED)-$(BUILD_DATETIME)-$(GIT_INFO).tar.xz
	rm -rf duktape-site-$(DUK_VERSION_FORMATTED)

ifeq ($(TRAVIS),1)
CODEPOLICYOPTS=--fail-on-errors
else
CODEPOLICYOPTS=
endif

.PHONY: codepolicycheck
codepolicycheck:
	python util/check_code_policy.py \
		$(CODEPOLICYOPTS) \
		--check-debug-log-calls \
		--check-carriage-returns \
		--check-fixme \
		--check-non-ascii \
		--check-no-symbol-visibility \
		--check-rejected-identifiers \
		--check-trailing-whitespace \
		--check-mixed-indent \
		--check-nonleading-tab \
		--check-cpp-comment \
		--dump-vim-commands \
		src/*.c src/*.h src/*.h.in tests/api/*.c
	python util/check_code_policy.py \
		$(CODEPOLICYOPTS) \
		--check-debug-log-calls \
		--check-carriage-returns \
		--check-fixme \
		--check-no-symbol-visibility \
		--check-trailing-whitespace \
		--check-mixed-indent \
		--check-nonleading-tab \
		--dump-vim-commands \
		tests/ecmascript/*.js
	python util/check_code_policy.py \
		$(CODEPOLICYOPTS) \
		--check-carriage-returns \
		--check-fixme \
		--check-non-ascii \
		--check-trailing-whitespace \
		--check-mixed-indent \
		--check-nonleading-tab \
		--check-cpp-comment \
		--dump-vim-commands \
		examples/*/*.c examples/*/*.h
	# XXX: not yet FIXME pure
	python util/check_code_policy.py \
		$(CODEPOLICYOPTS) \
		--check-carriage-returns \
		--check-non-ascii \
		--check-trailing-whitespace \
		--check-mixed-indent \
		--check-nonleading-tab \
		--dump-vim-commands \
		config/config-options/*.yaml config/feature-options/*.yaml config/*.yaml
	python util/check_code_policy.py \
		$(CODEPOLICYOPTS) \
		--check-carriage-returns \
		--check-fixme \
		--check-non-ascii \
		--check-trailing-whitespace \
		--check-mixed-indent \
		--check-nonleading-tab \
		--dump-vim-commands \
		debugger/*.yaml
	python util/check_code_policy.py \
		$(CODEPOLICYOPTS) \
		--check-carriage-returns \
		--check-fixme \
		--check-non-ascii \
		--check-trailing-whitespace \
		--check-mixed-indent \
		--check-nonleading-tab \
		--dump-vim-commands \
		website/api/*.yaml website/api/*.html

.PHONY: codepolicycheckvim
codepolicycheckvim:
	-python util/check_code_policy.py --dump-vim-commands src/*.c src/*.h src/*.h.in tests/api/*.c

.PHONY: big-git-files
big-git-files:
	util/find_big_git_files.sh

# Alignment check
.PHONY: checkalign
checkalign:
	@echo "checkalign for: `uname -a`"
	gcc -o /tmp/check_align -Wall -Wextra util/check_align.c
	@cp util/check_align.sh /tmp
	@cd /tmp; sh check_align.sh

# Simple heap graph and peak usage using valgrind --tool=massif, for quick
# and dirty baseline comparison.  Say e.g. 'make massif-test-dev-hello-world'.
# The target name is intentionally not 'massif-%.out' so that the rule is never
# satisfied and can be executed multiple times without cleaning.
# Grep/sed hacks from:
# http://stackoverflow.com/questions/774556/peak-memory-usage-of-a-linux-unix-process
massif-%: tests/ecmascript/%.js duk
	@rm -f $(@).out
	valgrind --tool=massif --peak-inaccuracy=0.0 --massif-out-file=$(@).out ./duk $< >/dev/null 2>/dev/null
	@ms_print $(@).out | head -35
	@echo "[... clipped... ]"
	@echo ""
	@echo -n "MAXIMUM: "
	@cat $(@).out | grep mem_heap_B | sed -e 's/mem_heap_B=\(.*\)/\1/' | sort -g | tail -n 1

# Convenience targets
massif-helloworld: massif-test-dev-hello-world
massif-deepmerge: massif-test-dev-deepmerge
massif-arcfour: massif-test-dev-arcfour

# Simple performance test, minimum time for N runs
# - Duktape is interpreted and uses reference counting
# - Python and Perl are interpreted and also use reference counting
# - Ruby and Lua are interpreted but don't use reference counting
# - Mujs is interpreted but doesn't use reference counting
# - Rhino compiles to Java bytecode and is ultimately JITed
# - Node.js (V8) is JITed
# - Luajit is JITed

#TIME=python util/time_multi.py --count 1 --sleep 0 --sleep-factor 0.8 --mode min # Take minimum time of N
#TIME=python util/time_multi.py --count 3 --sleep 0 --sleep-factor 0.8 --mode min # Take minimum time of N
TIME=python util/time_multi.py --count 5 --sleep 0 --sleep-factor 0.8 --mode min # Take minimum time of N

# Blocks: optimization variants, previous versions, other interpreting engines,
# other JIT engines.
perftest: duk duk.O2 duk.O3 duk.O4
	for i in tests/perf/*.js; do \
		printf '%-36s:' "`basename $$i`"; \
		printf ' duk.Os %5s' "`$(TIME) ./duk $$i`"; \
		printf ' duk.O2 %5s' "`$(TIME) ./duk.O2 $$i`"; \
		printf ' duk.O3 %5s' "`$(TIME) ./duk.O3 $$i`"; \
		printf ' duk.O4 %5s' "`$(TIME) ./duk.O4 $$i`"; \
		printf ' |'; \
		printf ' duk.O2.130 %5s' "`$(TIME) ./duk.O2.130 $$i`"; \
		printf ' duk.O2.124 %5s' "`$(TIME) ./duk.O2.124 $$i`"; \
		printf ' duk.O2.113 %5s' "`$(TIME) ./duk.O2.113 $$i`"; \
		printf ' duk.O2.102 %5s' "`$(TIME) ./duk.O2.102 $$i`"; \
		printf ' |'; \
		printf ' mujs %5s' "`$(TIME) mujs $$i`"; \
		printf ' lua %5s' "`$(TIME) lua $${i%%.js}.lua`"; \
		printf ' python %5s' "`$(TIME) python $${i%%.js}.py`"; \
		printf ' perl %5s' "`$(TIME) perl $${i%%.js}.pl`"; \
		printf ' ruby %5s' "`$(TIME) ruby $${i%%.js}.rb`"; \
		printf ' |'; \
		printf ' rhino %5s' "`$(TIME) rhino $$i`"; \
		printf ' node %5s' "`$(TIME) node $$i`"; \
		printf ' luajit %5s' "`$(TIME) luajit $${i%%.js}.lua`"; \
		printf '\n'; \
	done
perftestduk: duk duk.O2
	for i in tests/perf/*.js; do \
		printf '%-36s:' "`basename $$i`"; \
		printf ' duk.Os %5s' "`$(TIME) ./duk $$i`"; \
		printf ' duk.O2 %5s' "`$(TIME) ./duk.O2 $$i`"; \
		printf ' |'; \
		printf ' duk.O2.130 %5s' "`$(TIME) ./duk.O2.130 $$i`"; \
		printf ' duk.O2.124 %5s' "`$(TIME) ./duk.O2.124 $$i`"; \
		printf ' duk.O2.113 %5s' "`$(TIME) ./duk.O2.113 $$i`"; \
		printf ' duk.O2.102 %5s' "`$(TIME) ./duk.O2.102 $$i`"; \
		printf '\n'; \
	done
perftestduk3: duk.O2
	for i in tests/perf/*.js; do \
		printf '%-36s:' "`basename $$i`"; \
		printf ' duk.O2'; \
		printf ' %5s' "`$(TIME) ./duk.O2 $$i`"; \
		printf ' %5s' "`$(TIME) ./duk.O2 $$i`"; \
		printf ' %5s' "`$(TIME) ./duk.O2 $$i`"; \
		printf '\n'; \
	done


text:
ZE2 A private constructor cannot be called
--FILE--
<?php

class Test
{
    function __construct()
    {
        echo __METHOD__ . "()\n";
    }
}

class Derived extends Test
{
	function __construct()
	{
        echo __METHOD__ . "()\n";
		parent::__construct();
	}

	static function f()
	{
		new Derived;
	}
}

Derived::f();

class TestPriv
{
    private function __construct()
    {
        echo __METHOD__ . "()\n";
    }

	static function f()
	{
		new TestPriv;
	}
}

TestPriv::f();

class DerivedPriv extends TestPriv
{
	function __construct()
	{
        echo __METHOD__ . "()\n";
		parent::__construct();
	}

	static function f()
	{
		new DerivedPriv;
	}
}

DerivedPriv::f();

?>
===DONE===
--EXPECTF--
Derived::__construct()
Test::__construct()
TestPriv::__construct()
DerivedPriv::__construct()

Fatal error: Call to private method TestPriv::__construct() from context 'DerivedPriv' in %s on line %d, position %d


text:
package com.eaw1805.www.controllers.remote.hotspot.navy;

import com.eaw1805.data.constants.ArmyConstants;
import com.eaw1805.data.dto.common.PositionDTO;
import com.eaw1805.data.dto.web.OrderDTO;
import com.eaw1805.data.dto.web.TransportUnitDTO;
import com.eaw1805.data.dto.web.fleet.FleetDTO;
import com.eaw1805.data.dto.web.fleet.ShipDTO;
import com.eaw1805.www.controllers.remote.hotspot.AbstractChangesProcessor;
import com.eaw1805.www.controllers.remote.hotspot.ChangesProcessor;
import com.eaw1805.www.shared.orders.navy.ChangeFleetNameOrder;
import com.eaw1805.www.shared.orders.navy.ChangeShipFleetOrder;
import com.eaw1805.www.shared.orders.navy.CreateFleetOrder;
import com.eaw1805.www.shared.orders.navy.DeleteFleetOrder;
import com.eaw1805.www.shared.orders.navy.HandOverShipOrder;
import com.eaw1805.www.shared.orders.navy.ScuttleShipOrder;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class NavyApplyChangesProcessor
        extends AbstractChangesProcessor
        implements ChangesProcessor, ArmyConstants {

    /**
     * The order types that this processor is handling.
     */
    public static final Object[] ORDERS_TYPES = {
            ORDER_B_FLT,
            ORDER_D_FLT,
            ORDER_ADDTO_FLT,
            ORDER_REN_FLT,
            ORDER_REN_SHIP,
            ORDER_HOVER_SHIP,
            ORDER_R_FLT,
            ORDER_R_SHP,
            ORDER_LOAD_TROOPSF,
            ORDER_LOAD_TROOPSS,
            ORDER_UNLOAD_TROOPSF,
            ORDER_UNLOAD_TROOPSS,
            ORDER_SCUTTLE_SHIP,
            ORDER_M_UNIT,
            ORDER_M_FLEET,
            ORDER_M_SHIP,
            ORDER_P_FLEET,
            ORDER_P_SHIP

    };

    public static final Object[] ORDERS_TYPES_ALLIED = {
            ORDER_R_FLT,
            ORDER_R_SHP
    };

    public static final Object[] ORDERS_TYPES_CURRENT_FOR_ALLIES = {
            ORDER_LOAD_TROOPSF,
            ORDER_LOAD_TROOPSS,
            ORDER_UNLOAD_TROOPSF,
            ORDER_UNLOAD_TROOPSS
    };

    /**
     * A list containing all the available fleets as taken from the service
     */
    private transient List<FleetDTO> dbFleetlist = new ArrayList<FleetDTO>();

    /**
     * A hash map containing all the fleet ids and their corresponding objects
     */
    private transient final Map<Integer, FleetDTO> idFleetMap = new HashMap<Integer, FleetDTO>();

    private transient final Map<Integer, FleetDTO> idDeletedFleetMap = new HashMap<Integer, FleetDTO>();

    /**
     * A hash map containing all the ship ids and their corresponding objects
     */
    private transient final Map<Integer, ShipDTO> idShipMap = new HashMap<Integer, ShipDTO>();

    private transient List<OrderDTO> orders = new ArrayList<OrderDTO>();

    /**
     * Default constructor.
     *
     * @param thisGame   the game of the order.
     * @param thisNation the owner of the order.
     * @param thisTurn   the turn of the order.
     */
    public NavyApplyChangesProcessor(final int thisScenario, final int thisGame, final int thisNation, final int thisTurn) {
        super(thisScenario, thisGame, thisNation, thisTurn);
    }

    @SuppressWarnings({"unchecked", "restriction"})
    public void addData(final Collection<?> dbData, final Collection<?> chOrders) {
        // clear any previous additions to collections
        dbFleetlist = (List<FleetDTO>) dbData;
        for (final FleetDTO fleet : dbFleetlist) {
            // Fleet with id -1 is a dummy fleet and
            // we don't want it in our data
            // If there is no such fleet in our map
            if (fleet.getFleetId() != -1 && !idFleetMap.containsKey(fleet.getFleetId())) {
                // Make one.
                idFleetMap.put(fleet.getFleetId(), fleet);

                // Add all fleet ships
                for (final ShipDTO ship : fleet.getShips().values()) {
                    idShipMap.put(ship.getId(), ship);
                }
            }
        }

        orders = (List<OrderDTO>) chOrders;
    }

    @SuppressWarnings({"unchecked", "restriction"})
    public void addData(final Map<?, ?> dbData, final Map<?, ?> chData) {
        // do nothing
    }

    public List<FleetDTO> processChanges() {
        for (OrderDTO order : orders) {
            switch (order.getType()) {
                case ORDER_B_FLT: {
                    execOrderBuild(order);
                    break;
                }

                case ORDER_D_FLT: {
                    execOrderDel(order);
                    break;
                }

                case ORDER_ADDTO_FLT: {
                    execOrderAdd(order);
                    break;
                }

                case ORDER_REN_FLT: {
                    execOrderRename(order);
                    break;
                }

                case ORDER_REN_SHIP: {
                    final int shipId = Integer.parseInt(order.getParameter1());
                    if (idShipMap.containsKey(shipId)) {
                        idShipMap.get(shipId).setName(order.getParameter2());
                    }
                    break;
                }

                case ORDER_HOVER_SHIP: {
                    execOrderHandover(order);
                    break;
                }

                case ORDER_R_FLT:
                    if (Integer.parseInt(order.getParameter4()) == getNationId()) {
                        final int fleetId = Integer.parseInt(order.getParameter1());
                        final FleetDTO fleet = idFleetMap.get(fleetId);
                        //when setting up navy for allied nations because we do this by region
                        //this fleet will be null in 3 out of 4 regions.
                        if (fleet != null) {
                            for (ShipDTO ship : fleet.getShips().values()) {
                                //update the ships status to 100% since it gets repaired
                                ship.setCondition(100);
                                ship.setMarines(ship.getType().getCitizens());
                            }
                        }
                    }
                    break;

                case ORDER_R_SHP: {
                    if (Integer.parseInt(order.getParameter4()) == getNationId()) {
                        final int shipId = Integer.parseInt(order.getParameter1());
                        final ShipDTO ship = getShipById(shipId);
                        //when setting up navy for allied nations because we do this by region
                        //this ship will be null in 3 out of 4 regions.
                        if (ship != null) {
                            ship.setCondition(100);
                            ship.setMarines(ship.getType().getCitizens());
                        }
                    }
                    break;
                }

                case ORDER_LOAD_TROOPSF:
                case ORDER_LOAD_TROOPSS:
                    switch (Integer.parseInt(order.getParameter1())) {
                        case FLEET:
                            loadUnitOnFleet(Integer.parseInt(order.getParameter2()),
                                    Integer.parseInt(order.getParameter3()),
                                    Integer.parseInt(order.getParameter4()));
                            break;

                        case SHIP:
                            loadUnitOnShip(Integer.parseInt(order.getParameter2()),
                                    Integer.parseInt(order.getParameter3()),
                                    Integer.parseInt(order.getParameter4()));
                            break;

                        default:
                            // do nothing
                    }
                    break;

                case ORDER_UNLOAD_TROOPSF:
                case ORDER_UNLOAD_TROOPSS:
                    switch (Integer.parseInt(order.getParameter1())) {
                        case FLEET:
                            unloadUnitOnFleet(Integer.parseInt(order.getParameter2()),
                                    Integer.parseInt(order.getParameter3()),
                                    Integer.parseInt(order.getParameter4()));
                            break;

                        case SHIP:
                            unloadUnitOnShip(Integer.parseInt(order.getParameter2()),
                                    Integer.parseInt(order.getParameter3()),
                                    Integer.parseInt(order.getParameter4()));
                            break;

                        default:
                            // do nothing
                    }
                    break;

                case ORDER_SCUTTLE_SHIP: {
                    execOrderScuttle(order);
                    break;
                }

                case ORDER_M_FLEET:
                case ORDER_M_SHIP:
                case ORDER_M_UNIT:
                    final int unitType = Integer.parseInt(order.getParameter1());
                    if (order.getType() != ORDER_M_UNIT || (unitType == FLEET || unitType == SHIP)
                            && !order.getParameter3().isEmpty()) {
                        final PositionDTO pos = getLastPositionByString(order.getParameter3());
                        moveUnitByTypeToNewPosition(Integer.parseInt(order.getParameter1()),
                                Integer.parseInt(order.getParameter2()), pos);
                    }
                case ORDER_P_FLEET:
                case ORDER_P_SHIP:
                    // Patrol orders need not move the ship or fleet
                    break;

                default:
                    // do nothing
            }
        }

        return dbFleetlist;
    }

    private void execOrderBuild(final OrderDTO order) {
        final int fleetId = Integer.parseInt(order.getParameter1());
        if (!idFleetMap.containsKey(fleetId)) {
            final CreateFleetOrder cfOrder = new CreateFleetOrder(idFleetMap,
                    order.getParameter2(),
                    null,
                    Integer.parseInt(order.getParameter4()),
                    Integer.parseInt(order.getParameter5()),
                    Integer.parseInt(order.getParameter6()),
                    getNationId());
            cfOrder.execute(fleetId);
            dbFleetlist.add(idFleetMap.get(fleetId));
        }
    }

    private void execOrderDel(final OrderDTO order) {
        final int fleetId = Integer.parseInt(order.getParameter1());

        if (idFleetMap.containsKey(fleetId) &&//be sure the fleet is in the map.. not sure for allied units
                !(idFleetMap.get(fleetId).getShips().values().size() > 0)) {
            final DeleteFleetOrder dfOrder = new DeleteFleetOrder(idFleetMap, fleetId, idDeletedFleetMap);
            dfOrder.execute(fleetId);
            final Iterator<FleetDTO> iter = dbFleetlist.iterator();
            while (iter.hasNext()) {
                if (iter.next().getFleetId() == fleetId) {
                    iter.remove();
                    break;
                }
            }
        }
    }

    private void execOrderAdd(final OrderDTO order) {
        final int newFleetId = Integer.parseInt(order.getParameter2());
        final int shipId = Integer.parseInt(order.getParameter1());
        if (newFleetId == 0) {//check if the dummy fleet is initialized in the map
            if (!idFleetMap.containsKey(0)) {
                FleetDTO dummyFleet = new FleetDTO();
                dummyFleet.setName("Free Ships");
                dummyFleet.setOriginalName("Free Ships");
                dummyFleet.setFleetId(0);
                dummyFleet.setNationId(getGameId());
                dummyFleet.setShips(new HashMap<Integer, ShipDTO>());
                idFleetMap.put(0, dummyFleet);
                dbFleetlist.add(dummyFleet);
            }
        }
        final ChangeShipFleetOrder csfOrder = new ChangeShipFleetOrder(idFleetMap, newFleetId);
        csfOrder.execute(shipId);

        //now check source fleet
        final FleetDTO source = csfOrder.getSource();
        if (source != null && source.getShips().isEmpty()) {//if the fleet has no more ships then disband it.
            final DeleteFleetOrder dfOrder = new DeleteFleetOrder(idFleetMap, source.getFleetId(), idDeletedFleetMap);
            dfOrder.execute(source.getFleetId());
            final Iterator<FleetDTO> iter = dbFleetlist.iterator();
            while (iter.hasNext()) {
                if (iter.next().getFleetId() == source.getFleetId()) {
                    iter.remove();
                    break;
                }
            }
        }

    }

    private void execOrderRename(final OrderDTO order) {
        final int fleetId = Integer.parseInt(order.getParameter1());
        final ChangeFleetNameOrder cfnOrder = new ChangeFleetNameOrder(idFleetMap, order.getParameter2());
        cfnOrder.execute(fleetId);
    }

    private void execOrderHandover(final OrderDTO order) {
        final int shipId = Integer.parseInt(order.getParameter1());
        final HandOverShipOrder cfnOrder = new HandOverShipOrder(idShipMap, Integer.parseInt(order.getParameter2()));
        cfnOrder.execute(shipId);
    }

    private void execOrderScuttle(final OrderDTO order) {
        final int shipId = Integer.parseInt(order.getParameter1());
        final ScuttleShipOrder sbtOrder = new ScuttleShipOrder(idShipMap, true);
        sbtOrder.execute(shipId);
    }

    public Map<Integer, ShipDTO> getIdShipMap() {
        return idShipMap;
    }

    public Map<Integer, FleetDTO> getIdDeletedFleetMap() {
        return idDeletedFleetMap;
    }

    /**
     * Method that returns a ship with a given id.
     *
     * @param shipId the id of the ship.
     * @return the ship or null when the ship is not
     *         found.
     */
    private ShipDTO getShipById(final int shipId) {
        if (idShipMap.containsKey(shipId)) {
            return idShipMap.get(shipId);
        }

        return null;
    }

    /**
     * Method that returns the last movement sector depending
     * to the movement string saved in the database
     *
     * @param movementString the target movement string
     * @return the position dto object
     */
    private PositionDTO getLastPositionByString(final String movementString) {
        final PositionDTO lastPosition = new PositionDTO();
        final String[] moves = movementString.split("!");
        final String lastMove = moves[moves.length - 1];
        final String[] sectors = lastMove.split("-");
        final String lastSector = sectors[sectors.length - 1];
        final String[] coords = lastSector.split(":");

        lastPosition.setX(Integer.parseInt(coords[0]));
        lastPosition.setY(Integer.parseInt(coords[1]));

        return lastPosition;
    }

    /**
     * Moves a unit to the specified position
     *
     * @param type the type of the unit
     * @param id   the id of the unit
     * @param pos  the specified position
     */
    private void moveUnitByTypeToNewPosition(final int type, final int id, final PositionDTO pos) {
        PositionDTO oldPos = null;
        switch (type) {
            case FLEET:
                oldPos = idFleetMap.get(id);
                if (oldPos != null) {
                    for (final ShipDTO ship : ((FleetDTO) oldPos).getShips().values()) {
                        moveUnitByTypeToNewPosition(SHIP, ship.getId(), pos);
                    }
                }
                break;

            case SHIP:
                oldPos = getShipById(id);
                break;

            default:
                // do nothing
        }

        if (oldPos != null) {
            oldPos.setX(pos.getX());
            oldPos.setY(pos.getY());
        }
    }

    /**
     * Method that loads a unit on a fleet without setting
     * any other information. On client side use LoadUnit
     *
     * @param fleetId   the id of the fleet
     * @param cargoType the type of the cargo
     * @param cargoId   the id of the cargo
     */
    private void loadUnitOnFleet(final int fleetId, final int cargoType, final int cargoId) {
        final TransportUnitDTO tUnit = idFleetMap.get(fleetId);
        if (tUnit != null) {
            // Make sure that a list exists for the specific cargo type
            if (!tUnit.getLoadedUnitsMap().containsKey(cargoType)) {
                tUnit.getLoadedUnitsMap().put(cargoType, new ArrayList<Integer>());
            }
            tUnit.getLoadedUnitsMap().get(cargoType).add(cargoId);
        }
    }

    /**
     * Method that loads a unit on a ship without setting
     * any other information. On client side use LoadUnit
     *
     * @param shipId    the id of the ship
     * @param cargoType the type of the cargo
     * @param cargoId   the id of the cargo
     */
    private void loadUnitOnShip(final int shipId, final int cargoType, final int cargoId) {
        final ShipDTO tUnit = getShipById(shipId);
        if (tUnit != null) {
            if (!tUnit.getLoadedUnitsMap().containsKey(cargoType)) {
                tUnit.getLoadedUnitsMap().put(cargoType, new ArrayList<Integer>());
            }
            tUnit.getLoadedUnitsMap().get(cargoType).add(cargoId);
        }
    }

    /**
     * Method that unloads a unit from a fleet without setting
     * any other information. On client side use UnLoadUnit
     *
     * @param fleetId   the id of the fleet
     * @param cargoType the type of the cargo
     * @param cargoId   the id of the cargo
     */
    private void unloadUnitOnFleet(final int fleetId, final int cargoType, final Integer cargoId) {
        final TransportUnitDTO tUnit = idFleetMap.get(fleetId);
        if (tUnit != null) {
            if (tUnit.getLoadedUnitsMap().containsKey(cargoType)) {
                tUnit.getLoadedUnitsMap().get(cargoType).remove(cargoId);
            }
        }
    }

    /**
     * Method that unloads a unit on a ship without setting
     * any other information. On client side use UnLoadUnit
     *
     * @param shipId    the id of the ship
     * @param cargoType the type of the cargo
     * @param cargoId   the id of the cargo
     */
    private void unloadUnitOnShip(final int shipId, final int cargoType, final Integer cargoId) {
        final ShipDTO tUnit = getShipById(shipId);
        if (tUnit != null) {
            tUnit.getLoadedUnitsMap().get(cargoType).remove(cargoId);
        }
    }

}


text:
<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <stroke
        android:color="@color/red"
android:width="2dp"
        android:dashGap="3dp"
        android:dashWidth="10dp" />

    <size android:height="@dimen/widget_circle"
        android:width="@dimen/widget_circle" />

</shape>


text:
<?php

namespace Go\ParserReflection\Stub;

function miscScalarParameters(
    int $acceptsInteger,
    string $acceptsString,
    float $acceptsFloat = \INF,
    boolean $acceptsBool,
    int $acceptsVariadicInteger,
    string ...$acceptsDefaultString
) {
}


text: go-bindata assets/... templates/


text:
@interface MOBProjectionEPSG32609 : MOBProjection

@end


text:
<?php

namespace Webiny\Component\Security;

use Webiny\Component\Config\ConfigObject;
use Webiny\Component\EventManager\EventManagerTrait;
use Webiny\Component\Security\Authentication\Firewall;
use Webiny\Component\Security\Encoder\Drivers\Crypt;
use Webiny\Component\Security\Encoder\Drivers\Plain;
use Webiny\Component\Security\Encoder\Encoder;
use Webiny\Component\Security\User\UserProviderInterface;
use Webiny\Component\StdLib\ComponentTrait;
use Webiny\Component\StdLib\FactoryLoaderTrait;
use Webiny\Component\StdLib\SingletonTrait;
use Webiny\Component\StdLib\StdLibTrait;

/**
 * The security class initializes the whole security layer that consists of firewall and access controls.
 * The class checks if we are inside the firewall, and what is the state of the current user, is he authenticated or not.
 * Once we have the user, the security class check with the authorization layer (UAC) what roles are required to access
 * the current part of the site, and check is current user has the necessary role to enter this area.
 *
 * @package         Webiny\Component\Security
 */
class Security
{
    use SingletonTrait, StdLibTrait, FactoryLoaderTrait, EventManagerTrait, ComponentTrait;

    /**
     * Current firewall that took over the request.
     * @var Firewall
     */
    private $firewalls;

    /**
     * @var array A list of currently built-in user providers. The keys are used so you don't need to write
     *            the fully qualified class names in the yaml config.
     */
    private static $userProviders = [
        'Entity'       => User\Providers\Entity\Entity::class,
        'Memory'       => User\Providers\Memory\Memory::class,
        'OAuth2'       => User\Providers\OAuth2\OAuth2::class,
        'TwitterOAuth' => User\Providers\TwitterOAuth\TwitterOAuth::class
    ];

    /**
     * @var array A list of currently built-in encoders. The keys are used so you don't need to write
     *            the fully qualified class names in the yaml config.
     */
    private static $encoders = [
        'Crypt' => Crypt::class,
        'Plain' => Plain::class
    ];

    /**
     * Initializes the security layer for a specific firewall.
     *
     * @param string $firewallKey Name of the firewall you wish to return.
     *                            If you don't pass the name param, the first firewall from your configuration
     *                            will be used.
     *
     * @throws SecurityException
     * @return Firewall
     */
    public function firewall($firewallKey = '')
    {
        // initialize firewall
        if (isset($this->firewalls[$firewallKey])) {
            $fw = $this->firewalls[$firewallKey];
        } else {
            if ($firewallKey == '') {
                $firewall = $this->getConfig()->Firewalls[0];
                if (empty($firewall)) {
                    throw new SecurityException("There are no firewalls defined inside your configuration.");
                }
            } else {
                $firewall = $this->getConfig()->Firewalls->get($firewallKey, false);

                if (!$firewall) {
                    throw new SecurityException("Firewall '" . $firewallKey . "' is not defined under Security.Firewalls.");
                }
            }

            $fw = new Firewall($firewallKey, $firewall, $this->getFirewallUserProviders($firewallKey),
                $this->getFirewallEncoder($firewallKey));

            $this->firewalls[$firewallKey] = $fw;
        }

        return $fw;
    }

    /**
     * Returns an array of instances of user providers for the given firewall.
     * NOTE: this function also checks for chain providers.
     *
     * @param string $firewallKey Firewall name.
     *
     * @return array Array of user provider instances for the given firewall.
     * @throws SecurityException
     */
    private function getFirewallUserProviders($firewallKey)
    {
        $userProviders = [];

        $firewallProviders = $this->getFirewallConfig($firewallKey)->get('UserProviders', false);
        if (!$firewallProviders || count($firewallProviders) < 1) {
            throw new SecurityException('User providers for firewall "' . $firewallKey . '" are not defined.');
        }

        $providers = $this->getConfig()->get('UserProviders', []);

        foreach ($firewallProviders as $pk) {

            // get global config
            $gConfig = $providers->get($pk, false);
            $params = null;

            // get firewall driver and params
            if (isset($gConfig->Driver)) {
                $driver = $gConfig->Driver;
                if (isset(self::$userProviders[$driver])) { // short-hand driver name in the global config
                    $driver = self::$userProviders[$driver];
                }
                $params = $gConfig->get('Params', null, true);
            } else {
                if (isset(self::$userProviders[$pk])) {
                    $driver = self::$userProviders[$pk];
                    if ($gConfig) {
                        $params = $gConfig->get('Params', null, true);
                    }
                } else {
                    throw new SecurityException('User providers "' . $pk . '" is missing a Driver.');
                }
            }

            // In case of memory user provider, we don't have the parameters, but we have the user accounts
            // these need to be passed to the constructor.
            // Not the best way to do it, but keeps the yaml config simpler
            if ($driver == self::$userProviders['Memory'] && $params == null) {
                $params = $gConfig->toArray();
            }

            try {
                $userProviders[$pk] = $this->factory($driver, UserProviderInterface::class, is_null($params) ? null : [$params]);
            } catch (\Exception $e) {
                throw new SecurityException($e->getMessage());
            }
        }

        if (count($userProviders) < 1) {
            throw new SecurityException('Unable to detect the user providers for "' . $firewallKey . '" firewall.');
        }

        return $userProviders;
    }

    /**
     * Returns the encoder instance for the given firewall.
     *
     * @param string $firewallKey Firewall name.
     *
     * @return Encoder
     * @throws SecurityException
     */
    private function getFirewallEncoder($firewallKey)
    {
        // get the encoder name
        $encoderName = $this->getFirewallConfig($firewallKey)->get('Encoder', 'Crypt');
        if (!$encoderName) {
            $encoderName = 'Plain';
        }

        // check if the encoder is defined in the global config
        $encoderConfig = $this->getConfig()->get('Encoders.' . $encoderName, false);

        // get the driver & params
        $driver = false;
        $params = null;
        if ($encoderConfig) {
            $driver = $encoderConfig->get('Driver', false);
            $params = $encoderConfig->get('Params', null, true);
        }

        // get the driver class name
        if (!$driver && isset(self::$encoders[$encoderName])) { // use built-in driver
            $driver = self::$encoders[$encoderName];
        } else {
            if (isset(self::$encoders[$driver])) { // driver defined as short-name built-in driver
                $driver = self::$encoders[$driver];
            } else {
                if (!$driver) {
                    throw new SecurityException('Invalid "Driver" param for "' . $encoderName . '" encoder.');
                }
            }
        }

        // create encoder instance
        return new Encoder($driver, $params);
    }

    /**
     * @param $firewallKey
     *
     * @return ConfigObject
     */
    private function getFirewallConfig($firewallKey)
    {
        return $this->getConfig()->Firewalls->{$firewallKey};
    }
}