# stack_data

[![Tests](https://github.com/alexmojaki/stack_data/actions/workflows/pytest.yml/badge.svg)](https://github.com/alexmojaki/stack_data/actions/workflows/pytest.yml) [![Coverage Status](https://coveralls.io/repos/github/alexmojaki/stack_data/badge.svg?branch=master)](https://coveralls.io/github/alexmojaki/stack_data?branch=master) [![Supports Python versions 3.5+](https://img.shields.io/pypi/pyversions/stack_data.svg)](https://pypi.python.org/pypi/stack_data)

This is a library that extracts data from stack frames and tracebacks, particularly to display more useful tracebacks than the default. It powers the tracebacks in IPython and [futurecoder](https://futurecoder.io/):

![futurecoder example](https://futurecoder.io/static/img/features/traceback.png)

You can install it from PyPI:

    pip install stack_data

## Basic usage

Here's some code we'd like to inspect:

```python
def foo():
    result = []
    for i in range(5):
        row = []
        result.append(row)
        print_stack()
        for j in range(5):
            row.append(i * j)
    return result
```

Note that `foo` calls a function `print_stack()`. In reality we can imagine that an exception was raised at this line, or a debugger stopped there, but this is easy to play with directly. Here's a basic implementation:

```python
import inspect
import stack_data

def print_stack():
    frame = inspect.currentframe().f_back
    frame_info = stack_data.FrameInfo(frame)
    print(f"{frame_info.code.co_name} at line {frame_info.lineno}")
    print("-----------")
    for line in frame_info.lines:
        print(f"{'-->' if line.is_current else '   '} {line.lineno:4} | {line.render()}")
```

(Beware that this has a major bug - it doesn't account for line gaps, which we'll learn about later)

The output of one call to `print_stack()` looks like:

```
foo at line 9
-----------
       6 | for i in range(5):
       7 |     row = []
       8 |     result.append(row)
-->    9 |     print_stack()
      10 |     for j in range(5):
```

The code for `print_stack()` is fairly self-explanatory. If you want to learn more details about a particular class or method I suggest looking through some docstrings. `FrameInfo` is a class that accepts either a frame or a traceback object and provides a bunch of nice attributes and properties (which are cached so you don't need to worry about performance). In particular `frame_info.lines` is a list of `Line` objects. `line.render()` returns the source code of that line suitable for display. Without any arguments it simply strips any common leading indentation. Later on we'll see a more powerful use for it.

You can see that `frame_info.lines` includes some lines of surrounding context. By default it includes 3 pieces of context before the main line and 1 piece after. We can configure the amount of context by passing options:

```python
options = stack_data.Options(before=1, after=0)
frame_info = stack_data.FrameInfo(frame, options)
```

Then the output looks like:

```
foo at line 9
-----------
       8 | result.append(row)
-->    9 | print_stack()
```

Note that these parameters are not the number of *lines* before and after to include, but the number of *pieces*. A piece is a range of one or more lines in a file that should logically be grouped together. A piece contains either a single simple statement or a part of a compound statement (loops, if, try/except, etc) that doesn't contain any other statements. Most pieces are a single line, but a multi-line statement or `if` condition is a single piece. In the example above, all pieces are one line, because nothing is spread across multiple lines. If we change our code to include some multiline bits:

```python
def foo():
    result = []
    for i in range(5):
        row = []
        result.append(
            row
        )
        print_stack()
        for j in range(
                5
        ):
            row.append(i * j)
    return result
```

and then run the original code with the default options, then the output is:

```
foo at line 11
-----------
       6 | for i in range(5):
       7 |     row = []
       8 |     result.append(
       9 |         row
      10 |     )
-->   11 |     print_stack()
      12 |     for j in range(
      13 |             5
      14 |     ):
```

Now lines 8-10 and lines 12-14 are each a single piece. Note that the output is essentially the same as the original in terms of the amount of code. The division of files into pieces means that the edge of the context is intuitive and doesn't crop out parts of statements or expressions. For example, if context was measured in lines instead of pieces, the last line of the above would be `for j in range(` which is much less useful.

However, if a piece is very long, including all of it could be cumbersome. For this, `Options` has a parameter `max_lines_per_piece`, which is 6 by default. Suppose we have a piece in our code that's longer than that:

```python
        row = [
            1,
            2,
            3,
            4,
            5,
        ]
```

`frame_info.lines` will truncate this piece so that instead of 7 `Line` objects it will produce 5 `Line` objects and one `LINE_GAP` in the middle, making 6 objects in total for the piece. Our code doesn't currently handle gaps, so it will raise an exception. We can modify it like so:

```python
    for line in frame_info.lines:
        if line is stack_data.LINE_GAP:
            print("       (...)")
        else:
            print(f"{'-->' if line.is_current else '   '} {line.lineno:4} | {line.render()}")
```

Now the output looks like:

```
foo at line 15
-----------
       6 | for i in range(5):
       7 |     row = [
       8 |         1,
       9 |         2,
       (...)
      12 |         5,
      13 |     ]
      14 |     result.append(row)
-->   15 |     print_stack()
      16 |     for j in range(5):
```

Alternatively, you can flip the condition around and check `if isinstance(line, stack_data.Line):`. Either way, you should always check for line gaps, or your code may appear to work at first but fail when it encounters a long piece.

Note that the executing piece, i.e. the piece containing the current line being executed (line 15 in this case) is never truncated, no matter how long it is.

The lines of context never stray outside `frame_info.scope`, which is the innermost function or class definition containing the current line. For example, this is the output for a short function which has neither 3 lines before nor 1 line after the current line:

```
bar at line 6
-----------
       4 | def bar():
       5 |     foo()
-->    6 |     print_stack()
```

Sometimes it's nice to ensure that the function signature is always showing. This can be done with `Options(include_signature=True)`. The result looks like this:

```
foo at line 14
-----------
       9 | def foo():
       (...)
      11 |     for i in range(5):
      12 |         row = []
      13 |         result.append(row)
-->   14 |         print_stack()
      15 |         for j in range(5):
```

To avoid wasting space, pieces never start or end with a blank line, and blank lines between pieces are excluded. So if our code looks like this:

```python
    for i in range(5):
        row = []

        result.append(row)
        print_stack()

        for j in range(5):
```

The output doesn't change much, except you can see jumps in the line numbers:

```
      11 |     for i in range(5):
      12 |         row = []
      14 |         result.append(row)
-->   15 |         print_stack()
      17 |         for j in range(5):
```

## Variables

You can also inspect variables and other expressions in a frame, e.g:

```python
    for var in frame_info.variables:
        print(f"{var.name} = {repr(var.value)}")
```

which may output:

```python
result = [[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12], []]
i = 4
row = []
j = 4
```

`frame_info.variables` returns a list of `Variable` objects, which have attributes `name`, `value`, and `nodes`, which is a list of all AST representing that expression.

A `Variable` may refer to an expression other than a simple variable name. It can be any expression evaluated by the library [`pure_eval`](https://github.com/alexmojaki/pure_eval) which it deems 'interesting' (see those docs for more info). This includes expressions like `foo.bar` or `foo[bar]`. In these cases `name` is the source code of that expression. `pure_eval` ensures that it only evaluates expressions that won't have any side effects, e.g. where `foo.bar` is a normal attribute rather than a descriptor such as a property.

`frame_info.variables` is a list of all the interesting expressions found in `frame_info.scope`, e.g. the current function, which may include expressions not visible in `frame_info.lines`. You can restrict the list by using `frame_info.variables_in_lines` or even `frame_info.variables_in_executing_piece`. For more control you can use `frame_info.variables_by_lineno`. See the docstrings for more information.

## Rendering lines with ranges and markers

Sometimes you may want to insert special characters into the text for display purposes, e.g. HTML or ANSI color codes. `stack_data` provides a few tools to make this easier.

Let's say we have a `Line` object where `line.text` (the original raw source code of that line) is `"foo = bar"`, so `line.text[6:9]` is `"bar"`, and we want to emphasise that part by inserting HTML at positions 6 and 9 in the text. Here's how we can do that directly:

```python
markers = [
    stack_data.MarkerInLine(position=6, is_start=True, string="<b>"),
    stack_data.MarkerInLine(position=9, is_start=False, string="</b>"),
]
line.render(markers)  # returns "foo = <b>bar</b>"
```

Here `is_start=True` indicates that the marker is the first of a pair. This helps `line.render()` sort and insert the markers correctly so you don't end up with malformed HTML like `foo<b>.<i></b>bar</i>` where tags overlap.

Since we're inserting HTML, we should actually use `line.render(markers, escape_html=True)` which will escape special HTML characters in the Python source (but not the markers) so for example `foo = bar < spam` would be rendered as `foo = <b>bar</b> < spam`.

Usually though you wouldn't create markers directly yourself. Instead you would start with one or more ranges and then convert them, like so:

```python
ranges = [
    stack_data.RangeInLine(start=0, end=3, data="foo"),
    stack_data.RangeInLine(start=6, end=9, data="bar"),
]

def convert_ranges(r):
    if r.data == "bar":
        return "<b>", "</b>"

# This results in `markers` being the same as in the above example.
markers = stack_data.markers_from_ranges(ranges, convert_ranges)
```

`RangeInLine` has a `data` attribute which can be any object. `markers_from_ranges` accepts a converter function to which it passes all the `RangeInLine` objects. If the converter function returns a pair of strings, it creates two markers from them. Otherwise it should return `None` to indicate that the range should be ignored, as with the first range containing `"foo"` in this example.

The reason this is useful is because there are built in tools to create these ranges for you. For example, if we change our `print_stack()` function to contain this:

```python
def convert_variable_ranges(r):
    variable, _node = r.data
    return f'<span data-value="{repr(variable.value)}">', '</span>'

markers = stack_data.markers_from_ranges(line.variable_ranges, convert_variable_ranges)
print(f"{'-->' if line.is_current else '   '} {line.lineno:4} | {line.render(markers, escape_html=True)}")
```

Then the output becomes:

```
foo at line 15
-----------
       9 | def foo():
       (...)
      11 |     for <span data-value="4">i</span> in range(5):
      12 |         <span data-value="[]">row</span> = []
      14 |         <span data-value="[[0, 0, 0, 0, 0], [0, 1, 2, 3, 4], [0, 2, 4, 6, 8], [0, 3, 6, 9, 12], []]">result</span>.append(<span data-value="[]">row</span>)
-->   15 |         print_stack()
      17 |         for <span data-value="4">j</span> in range(5):
```

`line.variable_ranges` is a list of RangeInLines for each Variable that appears at least partially in this line. The data attribute of the range is a pair `(variable, node)` where node is the particular AST node from the list `variable.nodes` that corresponds to this range.

You can also use `line.token_ranges` (e.g. if you want to do your own syntax highlighting) or `line.executing_node_ranges` if you want to highlight the currently executing node identified by the [`executing`](https://github.com/alexmojaki/executing) library. Or if you want to make your own range from an AST node, use `line.range_from_node(node, data)`. See the docstrings for more info.

### Syntax highlighting with Pygments

If you'd like pretty colored text without the work, you can let [Pygments](https://pygments.org/) do it for you. Just follow these steps:

1. `pip install pygments` separately as it's not a dependency of `stack_data`.
2. Create a pygments formatter object such as `HtmlFormatter` or `Terminal256Formatter`.
3. Pass the formatter to `Options` in the argument `pygments_formatter`.
4. Use `line.render(pygmented=True)` to get your formatted text. In this case you can't pass any markers to `render`.

If you want, you can also highlight the executing node in the frame in combination with the pygments syntax highlighting. For this you will need:

1. A pygments style - either a style class or a string that names it. See the [documentation on styles](https://pygments.org/docs/styles/) and the [styles gallery](https://blog.yjl.im/2015/08/pygments-styles-gallery.html).
2. A modification to make to the style for the executing node, which is a string such as `"bold"` or `"bg:#ffff00"` (yellow background). See the [documentation on style rules](https://pygments.org/docs/styles/#style-rules).
3. Pass these two things to `stack_data.style_with_executing_node(style, modifier)` to get a new style class.
4. Pass the new style to your formatter when you create it.

Note that this doesn't work with `TerminalFormatter` which just uses the basic ANSI colors and doesn't use the style passed to it in general.

## Getting the full stack

Currently `print_stack()` doesn't actually print the stack, it just prints one frame. Instead of `frame_info = FrameInfo(frame, options)`, let's do this:

```python
for frame_info in FrameInfo.stack_data(frame, options):
```

Now the output looks something like this:

```
<module> at line 18
-----------
      14 |         for j in range(5):
      15 |             row.append(i * j)
      16 |     return result
-->   18 | bar()

bar at line 5
-----------
       4 | def bar():
-->    5 |     foo()

foo at line 13
-----------
      10 | for i in range(5):
      11 |     row = []
      12 |     result.append(row)
-->   13 |     print_stack()
      14 |     for j in range(5):
```

However, just as `frame_info.lines` doesn't always yield `Line` objects, `FrameInfo.stack_data` doesn't always yield `FrameInfo` objects, and we must modify our code to handle that. Let's look at some different sample code:

```python
def factorial(x):
    return x * factorial(x - 1)

try:
    print(factorial(5))
except:
    print_stack()
```

In this code we've forgotten to include a base case in our `factorial` function so it will fail with a `RecursionError` and there'll be many frames with similar information. Similar to the built in Python traceback, `stack_data` avoids showing all of these frames. Instead you will get a `RepeatedFrames` object which summarises the information. See its docstring for more details.

Here is our updated implementation:

```python
def print_stack():
    for frame_info in FrameInfo.stack_data(sys.exc_info()[2]):
        if isinstance(frame_info, FrameInfo):
            print(f"{frame_info.code.co_name} at line {frame_info.lineno}")
            print("-----------")
            for line in frame_info.lines:
                print(f"{'-->' if line.is_current else '   '} {line.lineno:4} | {line.render()}")

            for var in frame_info.variables:
                print(f"{var.name} = {repr(var.value)}")

            print()
        else:
            print(f"... {frame_info.description} ...\n")
```

And the output:

```
<module> at line 9
-----------
       4 | def factorial(x):
       5 |     return x * factorial(x - 1)
       8 | try:
-->    9 |     print(factorial(5))
      10 | except:

factorial at line 5
-----------
       4 | def factorial(x):
-->    5 |     return x * factorial(x - 1)
x = 5

factorial at line 5
-----------
       4 | def factorial(x):
-->    5 |     return x * factorial(x - 1)
x = 4

... factorial at line 5 (996 times) ...

factorial at line 5
-----------
       4 | def factorial(x):
-->    5 |     return x * factorial(x - 1)
x = -993
```

In addition to handling repeated frames, we've passed a traceback object to `FrameInfo.stack_data` instead of a frame.

If you want, you can pass `collapse_repeated_frames=False` to `FrameInfo.stack_data` (not to `Options`) and it will just yield `FrameInfo` objects for the full stack.


.. image:: https://travis-ci.com/agronholm/typeguard.svg?branch=master
  :target: https://travis-ci.com/agronholm/typeguard
  :alt: Build Status
.. image:: https://coveralls.io/repos/agronholm/typeguard/badge.svg?branch=master&service=github
  :target: https://coveralls.io/github/agronholm/typeguard?branch=master
  :alt: Code Coverage
.. image:: https://readthedocs.org/projects/typeguard/badge/?version=latest
  :target: https://typeguard.readthedocs.io/en/latest/?badge=latest

This library provides run-time type checking for functions defined with
`PEP 484 <https://www.python.org/dev/peps/pep-0484/>`_ argument (and return) type annotations.

Four principal ways to do type checking are provided, each with its pros and cons:

#. the ``check_argument_types()`` and ``check_return_type()`` functions:

   * debugger friendly (except when running with the pydev debugger with the C extension installed)
   * does not work reliably with dynamically defined type hints (e.g. in nested functions)
#. the ``@typechecked`` decorator:

   * automatically type checks yields and sends of returned generators (regular and async)
   * adds an extra frame to the call stack for every call to a decorated function
#. the stack profiler hook (``with TypeChecker('packagename'):``) (deprecated):

   * emits warnings instead of raising ``TypeError``
   * requires very few modifications to the code
   * multiple TypeCheckers can be stacked/nested
   * does not work reliably with dynamically defined type hints (e.g. in nested functions)
   * may cause problems with badly behaving debuggers or profilers
   * cannot distinguish between an exception being raised and a ``None`` being returned
#. the import hook (``typeguard.importhook.install_import_hook()``):

   * automatically annotates classes and functions with ``@typechecked`` on import
   * no code changes required in target modules
   * requires imports of modules you need to check to be deferred until after the import hook has
     been installed
   * may clash with other import hooks

See the documentation_ for further instructions.

.. _documentation: https://typeguard.readthedocs.io/en/latest/

Perforator is a cluster-wide continuous profiling tool designed for large data centers


## Typing stubs for protobuf

This is a [PEP 561](https://peps.python.org/pep-0561/)
type stub package for the [`protobuf`](https://github.com/protocolbuffers/protobuf) package.
It can be used by type-checking tools like
[mypy](https://github.com/python/mypy/),
[pyright](https://github.com/microsoft/pyright),
[pytype](https://github.com/google/pytype/),
[Pyre](https://pyre-check.org/),
PyCharm, etc. to check code that uses `protobuf`. This version of
`types-protobuf` aims to provide accurate annotations for
`protobuf~=5.29.1`.

Partially generated using [mypy-protobuf==3.6.0](https://github.com/nipunn1313/mypy-protobuf/tree/v3.6.0) and libprotoc 28.1 on [protobuf v29.1](https://github.com/protocolbuffers/protobuf/releases/tag/v29.1) (python `protobuf==5.29.1`).

This stub package is marked as [partial](https://peps.python.org/pep-0561/#partial-stub-packages).
If you find that annotations are missing, feel free to contribute and help complete them.

This package is part of the [typeshed project](https://github.com/python/typeshed).
All fixes for types and metadata should be contributed there.
See [the README](https://github.com/python/typeshed/blob/main/README.md)
for more details. The source for this package can be found in the
[`stubs/protobuf`](https://github.com/python/typeshed/tree/main/stubs/protobuf)
directory.

This package was tested with
mypy 1.15.0,
pyright 1.1.389,
and pytype 2024.10.11.
It was generated from typeshed commit
[`73ebb9dfd7dfce93c5becde4dcdd51d5626853b8`](https://github.com/python/typeshed/commit/73ebb9dfd7dfce93c5becde4dcdd51d5626853b8).


wheel
=====

This is a command line tool for manipulating Python wheel files, as defined in
`PEP 427`_. It contains the following functionality:

* Convert ``.egg`` archives into ``.whl``
* Unpack wheel archives
* Repack wheel archives
* Add or remove tags in existing wheel archives

.. _PEP 427: https://www.python.org/dev/peps/pep-0427/

Historical note
---------------

This project used to contain the implementation of the setuptools_ ``bdist_wheel``
command, but as of setuptools v70.1, it no longer needs ``wheel`` installed for that to
work. Thus, you should install this **only** if you intend to use the ``wheel`` command
line tool!

.. _setuptools: https://pypi.org/project/setuptools/

Documentation
-------------

The documentation_ can be found on Read The Docs.

.. _documentation: https://wheel.readthedocs.io/

Code of Conduct
---------------

Everyone interacting in the wheel project's codebases, issue trackers, chat
rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.

.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md


Please submit a new Abseil Issue using the template below:

## [Short title of proposed API change(s)]

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

## Background

[Provide the background information that is required in order to evaluate the
proposed API changes. No controversial claims should be made here. If there are
design constraints that need to be considered, they should be presented here
**along with justification for those constraints**. Linking to other docs is
good, but please keep the **pertinent information as self contained** as
possible in this section.]

## Proposed API Change (s)

[Please clearly describe the API change(s) being proposed. If multiple changes,
please keep them clearly distinguished. When possible, **use example code
snippets to illustrate before-after API usages**. List pros-n-cons. Highlight
the main questions that you want to be answered. Given the Abseil project compatibility requirements, describe why the API change is safe.]


# How to Contribute to Abseil

We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.

NOTE: If you are new to GitHub, please start by reading [Pull Request
howto](https://help.github.com/articles/about-pull-requests/)

## Contributor License Agreement

Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution,
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.

You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.

## Contribution Guidelines

Potential contributors sometimes ask us if the Abseil project is the appropriate
home for their utility library code or for specific functions implementing
missing portions of the standard. Often, the answer to this question is "no".
We’d like to articulate our thinking on this issue so that our choices can be
understood by everyone and so that contributors can have a better intuition
about whether Abseil might be interested in adopting a new library.

### Priorities

Although our mission is to augment the C++ standard library, our goal is not to
provide a full forward-compatible implementation of the latest standard. For us
to consider a library for inclusion in Abseil, it is not enough that a library
is useful. We generally choose to release a library when it meets at least one
of the following criteria:

*   **Widespread usage** - Using our internal codebase to help gauge usage, most
    of the libraries we've released have tens of thousands of users.
*   **Anticipated widespread usage** - Pre-adoption of some standard-compliant
    APIs may not have broad adoption initially but can be expected to pick up
    usage when it replaces legacy APIs. `absl::from_chars`, for example,
    replaces existing code that converts strings to numbers and will therefore
    likely see usage growth.
*   **High impact** - APIs that provide a key solution to a specific problem,
    such as `absl::FixedArray`, have higher impact than usage numbers may signal
    and are released because of their importance.
*   **Direct support for a library that falls under one of the above** - When we
    want access to a smaller library as an implementation detail for a
    higher-priority library we plan to release, we may release it, as we did
    with portions of `absl/meta/type_traits.h`. One consequence of this is that
    the presence of a library in Abseil does not necessarily mean that other
    similar libraries would be a high priority.

### API Freeze Consequences

Via the
[Abseil Compatibility Guidelines](https://abseil.io/about/compatibility), we
have promised a large degree of API stability. In particular, we will not make
backward-incompatible changes to released APIs without also shipping a tool or
process that can upgrade our users' code. We are not yet at the point of easily
releasing such tools. Therefore, at this time, shipping a library establishes an
API contract which is borderline unchangeable. (We can add new functionality,
but we cannot easily change existing behavior.) This constraint forces us to
very carefully review all APIs that we ship.

## Coding Style

To keep the source consistent, readable, diffable and easy to merge, we use a
fairly rigid coding style, as defined by the
[google-styleguide](https://github.com/google/styleguide) project. All patches
will be expected to conform to the style outlined
[here](https://google.github.io/styleguide/cppguide.html).

## Guidelines for Pull Requests

*   If you are a Googler, it is required that you send us a Piper CL instead of
    using the GitHub pull-request process. The code propagation process will
    deliver the change to GitHub.

*   Create **small PRs** that are narrowly focused on **addressing a single
    concern**. We often receive PRs that are trying to fix several things at a
    time, but if only one fix is considered acceptable, nothing gets merged and
    both author's & review's time is wasted. Create more PRs to address
    different concerns and everyone will be happy.

*   For speculative changes, consider opening an [Abseil
    issue](https://github.com/abseil/abseil-cpp/issues) and discussing it first.
    If you are suggesting a behavioral or API change, consider starting with an
    [Abseil proposal template](ABSEIL_ISSUE_TEMPLATE.md).

*   Provide a good **PR description** as a record of **what** change is being
    made and **why** it was made. Link to a GitHub issue if it exists.

*   Don't fix code style and formatting unless you are already changing that
    line to address an issue. Formatting of modified lines may be done using
   `git clang-format`. PRs with irrelevant changes won't be merged. If
    you do want to fix formatting or style, do that in a separate PR.

*   Unless your PR is trivial, you should expect there will be reviewer comments
    that you'll need to address before merging. We expect you to be reasonably
    responsive to those comments, otherwise the PR will be closed after 2-3
    weeks of inactivity.

*   Maintain **clean commit history** and use **meaningful commit messages**.
    PRs with messy commit history are difficult to review and won't be merged.
    Use `rebase -i upstream/master` to curate your commit history and/or to
    bring in latest changes from master (but avoid rebasing in the middle of a
    code review).

*   Keep your PR up to date with upstream/master (if there are merge conflicts,
    we can't really merge your change).

*   **All tests need to be passing** before your change can be merged. We
    recommend you **run tests locally** (see below)

*   Exceptions to the rules can be made if there's a compelling reason for doing
    so. That is - the rules are here to serve us, not the other way around, and
    the rules need to be serving their intended purpose to be valuable.

*   All submissions, including submissions by project members, require review.

## Running Tests

If you have [Bazel](https://bazel.build/) installed, use `bazel test
--test_tag_filters="-benchmark" ...` to run the unit tests.

If you are running the Linux operating system and have
[Docker](https://www.docker.com/) installed, you can also run the `linux_*.sh`
scripts under the `ci/`(https://github.com/abseil/abseil-cpp/tree/master/ci)
directory to test Abseil under a variety of conditions.

## Abseil Committers

The current members of the Abseil engineering team are the only committers at
present.

## Release Process

Abseil lives at head, where latest-and-greatest code can be found.


# Abseil FAQ

## Is Abseil the right home for my utility library?

Most often the answer to the question is "no." As both the [About
Abseil](https://abseil.io/about/) page and our [contributing
guidelines](https://github.com/abseil/abseil-cpp/blob/master/CONTRIBUTING.md#contribution-guidelines)
explain, Abseil contains a variety of core C++ library code that is widely used
at [Google](https://www.google.com/). As such, Abseil's primary purpose is to be
used as a dependency by Google's open source C++ projects. While we do hope that
Abseil is also useful to the C++ community at large, this added constraint also
means that we are unlikely to accept a contribution of utility code that isn't
already widely used by Google.

## How to I set the C++ dialect used to build Abseil?

The short answer is that whatever mechanism you choose, you need to make sure
that you set this option consistently at the global level for your entire
project. If, for example, you want to set the C++ dialect to C++17, with
[Bazel](https://bazel/build/) as the build system and `gcc` or `clang` as the
compiler, there several ways to do this:
* Pass `--cxxopt=-std=c++17` on the command line (for example, `bazel build
  --cxxopt=-std=c++17 ...`)
* Set the environment variable `BAZEL_CXXOPTS` (for example,
  `BAZEL_CXXOPTS=-std=c++17`)
* Add `build --cxxopt=-std=c++17` to your [`.bazelrc`
  file](https://docs.bazel.build/versions/master/guide.html#bazelrc)

If you are using CMake as the build system, you'll need to add a line like
`set(CMAKE_CXX_STANDARD 17)` to your top level `CMakeLists.txt` file. If you
are developing a library designed to be used by other clients, you should
instead leave `CMAKE_CXX_STANDARD` unset and configure the minimum C++ standard
required by each of your library targets via `target_compile_features`. See the
[CMake build
instructions](https://github.com/abseil/abseil-cpp/blob/master/CMake/README.md)
for more information.

For a longer answer to this question and to understand why some other approaches
don't work, see the answer to ["What is ABI and why don't you recommend using a
pre-compiled version of
Abseil?"](#what-is-abi-and-why-dont-you-recommend-using-a-pre-compiled-version-of-abseil)

## What is ABI and why don't you recommend using a pre-compiled version of Abseil?

For the purposes of this discussion, you can think of
[ABI](https://en.wikipedia.org/wiki/Application_binary_interface) as the
compiled representation of the interfaces in code. This is in contrast to
[API](https://en.wikipedia.org/wiki/Application_programming_interface), which
you can think of as the interfaces as defined by the code itself. [Abseil has a
strong promise of API compatibility, but does not make any promise of ABI
compatibility](https://abseil.io/about/compatibility). Let's take a look at what
this means in practice.

You might be tempted to do something like this in a
[Bazel](https://bazel.build/) `BUILD` file:

```
# DON'T DO THIS!!!
cc_library(
    name = "my_library",
    srcs = ["my_library.cc"],
    copts = ["-std=c++17"],  # May create a mixed-mode compile!
    deps = ["@com_google_absl//absl/strings"],
)
```

Applying `-std=c++17` to an individual target in your `BUILD` file is going to
compile that specific target in C++17 mode, but it isn't going to ensure the
Abseil library is built in C++17 mode, since the Abseil library itself is a
different build target. If your code includes an Abseil header, then your
program may contain conflicting definitions of the same
class/function/variable/enum, etc. As a rule, all compile options that affect
the ABI of a program need to be applied to the entire build on a global basis.

C++ has something called the [One Definition
Rule](https://en.wikipedia.org/wiki/One_Definition_Rule) (ODR). C++ doesn't
allow multiple definitions of the same class/function/variable/enum, etc. ODR
violations sometimes result in linker errors, but linkers do not always catch
violations. Uncaught ODR violations can result in strange runtime behaviors or
crashes that can be hard to debug.

If you build the Abseil library and your code using different compile options
that affect ABI, there is a good chance you will run afoul of the One Definition
Rule. Examples of GCC compile options that affect ABI include (but aren't
limited to) language dialect (e.g. `-std=`), optimization level (e.g. `-O2`),
code generation flags (e.g. `-fexceptions`), and preprocessor defines
(e.g. `-DNDEBUG`).

If you use a pre-compiled version of Abseil, (for example, from your Linux
distribution package manager or from something like
[vcpkg](https://github.com/microsoft/vcpkg)) you have to be very careful to
ensure ABI compatibility across the components of your program. The only way you
can be sure your program is going to be correct regarding ABI is to ensure
you've used the exact same compile options as were used to build the
pre-compiled library. This does not mean that Abseil cannot work as part of a
Linux distribution since a knowledgeable binary packager will have ensured that
all packages have been built with consistent compile options. This is one of the
reasons we warn against - though do not outright reject - using Abseil as a
pre-compiled library.

Another possible way that you might afoul of ABI issues is if you accidentally
include two versions of Abseil in your program. Multiple versions of Abseil can
end up within the same binary if your program uses the Abseil library and
another library also transitively depends on Abseil (resulting in what is
sometimes called the diamond dependency problem). In cases such as this you must
structure your build so that all libraries use the same version of Abseil.
[Abseil's strong promise of API compatibility between
releases](https://abseil.io/about/compatibility) means the latest "HEAD" release
of Abseil is almost certainly the right choice if you are doing as we recommend
and building all of your code from source.

For these reasons we recommend you avoid pre-compiled code and build the Abseil
library yourself in a consistent manner with the rest of your code.

## What is "live at head" and how do I do it?

From Abseil's point-of-view, "live at head" means that every Abseil source
release (which happens on an almost daily basis) is either API compatible with
the previous release, or comes with an automated tool that you can run over code
to make it compatible. In practice, the need to use an automated tool is
extremely rare. This means that upgrading from one source release to another
should be a routine practice that can and should be performed often.

We recommend you update to the [latest commit in the `master` branch of
Abseil](https://github.com/abseil/abseil-cpp/commits/master) as often as
possible. Not only will you pick up bug fixes more quickly, but if you have good
automated testing, you will catch and be able to fix any [Hyrum's
Law](https://www.hyrumslaw.com/) dependency problems on an incremental basis
instead of being overwhelmed by them and having difficulty isolating them if you
wait longer between updates.

If you are using the [Bazel](https://bazel.build/) build system and its
[external dependencies](https://docs.bazel.build/versions/master/external.html)
feature, updating the
[`http_archive`](https://docs.bazel.build/versions/master/repo/http.html#http_archive)
rule in your
[`WORKSPACE`](https://docs.bazel.build/versions/master/be/workspace.html) for
`com_google_abseil` to point to the [latest commit in the `master` branch of
Abseil](https://github.com/abseil/abseil-cpp/commits/master) is all you need to
do. For example, on February 11, 2020, the latest commit to the master branch
was `98eb410c93ad059f9bba1bf43f5bb916fc92a5ea`. To update to this commit, you
would add the following snippet to your `WORKSPACE` file:

```
http_archive(
  name = "com_google_absl",
  urls = ["https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip"],  # 2020-02-11T18:50:53Z
  strip_prefix = "abseil-cpp-98eb410c93ad059f9bba1bf43f5bb916fc92a5ea",
  sha256 = "aabf6c57e3834f8dc3873a927f37eaf69975d4b28117fc7427dfb1c661542a87",
)
```

To get the `sha256` of this URL, run `curl -sL --output -
https://github.com/abseil/abseil-cpp/archive/98eb410c93ad059f9bba1bf43f5bb916fc92a5ea.zip
| sha256sum -`.

You can commit the updated `WORKSPACE` file to your source control every time
you update, and if you have good automated testing, you might even consider
automating this.

One thing we don't recommend is using GitHub's `master.zip` files (for example
[https://github.com/abseil/abseil-cpp/archive/master.zip](https://github.com/abseil/abseil-cpp/archive/master.zip)),
which are always the latest commit in the `master` branch, to implement live at
head. Since these `master.zip` URLs are not versioned, you will lose build
reproducibility. In addition, some build systems, including Bazel, will simply
cache this file, which means you won't actually be updating to the latest
release until your cache is cleared or invalidated.


# Abseil - C++ Common Libraries

The repository contains the Abseil C++ library code. Abseil is an open-source
collection of C++ code (compliant to C++14) designed to augment the C++
standard library.

## Table of Contents

- [About Abseil](#about)
- [Quickstart](#quickstart)
- [Building Abseil](#build)
- [Support](#support)
- [Codemap](#codemap)
- [Releases](#releases)
- [License](#license)
- [Links](#links)

## About Abseil

Abseil is an open-source collection of C++ library code designed to augment
the C++ standard library. The Abseil library code is collected from Google's
own C++ code base, has been extensively tested and used in production, and
is the same code we depend on in our daily coding lives.

In some cases, Abseil provides pieces missing from the C++ standard; in
others, Abseil provides alternatives to the standard for special needs
we've found through usage in the Google code base. We denote those cases
clearly within the library code we provide you.

Abseil is not meant to be a competitor to the standard library; we've
just found that many of these utilities serve a purpose within our code
base, and we now want to provide those resources to the C++ community as
a whole.

## Quickstart

If you want to just get started, make sure you at least run through the
[Abseil Quickstart](https://abseil.io/docs/cpp/quickstart). The Quickstart
contains information about setting up your development environment, downloading
the Abseil code, running tests, and getting a simple binary working.

## Building Abseil

[Bazel](https://bazel.build) and [CMake](https://cmake.org/) are the official
build systems for Abseil.
See the [quickstart](https://abseil.io/docs/cpp/quickstart) for more information
on building Abseil using the Bazel build system.
If you require CMake support, please check the [CMake build
instructions](CMake/README.md) and [CMake
Quickstart](https://abseil.io/docs/cpp/quickstart-cmake).

## Support

Abseil follows Google's [Foundational C++ Support
Policy](https://opensource.google/documentation/policies/cplusplus-support). See
[this
table](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md)
for a list of currently supported versions compilers, platforms, and build
tools.

## Codemap

Abseil contains the following C++ library components:

* [`base`](absl/base/)

 The `base` library contains initialization code and other code which
  all other Abseil code depends on. Code within `base` may not depend on any
  other code (other than the C++ standard library).
* [`algorithm`](absl/algorithm/)

 The `algorithm` library contains additions to the C++ `<algorithm>`
  library and container-based versions of such algorithms.
* [`cleanup`](absl/cleanup/)

 The `cleanup` library contains the control-flow-construct-like type
  `absl::Cleanup` which is used for executing a callback on scope exit.
* [`container`](absl/container/)

 The `container` library contains additional STL-style containers,
  including Abseil's unordered "Swiss table" containers.
* [`crc`](absl/crc/) The `crc` library contains code for
  computing error-detecting cyclic redundancy checks on data.
* [`debugging`](absl/debugging/)

 The `debugging` library contains code useful for enabling leak
  checks, and stacktrace and symbolization utilities.
* [`flags`](absl/flags/)

 The `flags` library contains code for handling command line flags for
  libraries and binaries built with Abseil.
* [`hash`](absl/hash/)

 The `hash` library contains the hashing framework and default hash
  functor implementations for hashable types in Abseil.
* [`log`](absl/log/)

 The `log` library contains `LOG` and `CHECK` macros and facilities
  for writing logged messages out to disk, `stderr`, or user-extensible
  destinations.
* [`memory`](absl/memory/)

 The `memory` library contains memory management facilities that augment
  C++'s `<memory>` library.
* [`meta`](absl/meta/)

 The `meta` library contains compatible versions of type checks
  available within C++14 and C++17 versions of the C++ `<type_traits>` library.
* [`numeric`](absl/numeric/)

 The `numeric` library contains 128-bit integer types as well as
  implementations of C++20's bitwise math functions.
* [`profiling`](absl/profiling/)

 The `profiling` library contains utility code for profiling C++
  entities.  It is currently a private dependency of other Abseil libraries.
* [`random`](absl/random/)

 The `random` library contains functions for generating psuedorandom
  values.
* [`status`](absl/status/)

 The `status` library contains abstractions for error handling,
  specifically `absl::Status` and `absl::StatusOr<T>`.
* [`strings`](absl/strings/)

 The `strings` library contains a variety of strings routines and
  utilities, including a C++14-compatible version of the C++17
  `std::string_view` type.
* [`synchronization`](absl/synchronization/)

 The `synchronization` library contains concurrency primitives (Abseil's
  `absl::Mutex` class, an alternative to `std::mutex`) and a variety of
  synchronization abstractions.
* [`time`](absl/time/)

 The `time` library contains abstractions for computing with absolute
  points in time, durations of time, and formatting and parsing time within
  time zones.
* [`types`](absl/types/)

 The `types` library contains non-container utility types, like a
  C++14-compatible version of the C++17 `std::optional` type.
* [`utility`](absl/utility/)

 The `utility` library contains utility and helper code.

## Releases

Abseil recommends users "live-at-head" (update to the latest commit from the
master branch as often as possible). However, we realize this philosophy doesn't
work for every project, so we also provide [Long Term Support
Releases](https://github.com/abseil/abseil-cpp/releases) to which we backport
fixes for severe bugs. See our [release
management](https://abseil.io/about/releases) document for more details.

## License

The Abseil C++ library is licensed under the terms of the Apache
license. See [LICENSE](LICENSE) for more information.

## Links

For more information about Abseil:

* Consult our [Abseil Introduction](https://abseil.io/about/intro)
* Read [Why Adopt Abseil](https://abseil.io/about/philosophy) to understand our
  design philosophy.
* Peruse our
  [Abseil Compatibility Guarantees](https://abseil.io/about/compatibility) to
  understand both what we promise to you, and what we expect of you in return.


# C++ Upgrade Tools

Abseil may occasionally release API-breaking changes. As noted in our
[Compatibility Guidelines][compatibility-guide], we will aim to provide a tool
to do the work of effecting such API-breaking changes, when absolutely
necessary.

These tools will be listed on the [C++ Upgrade Tools][upgrade-tools] guide on
https://abseil.io.

For more information, the [C++ Automated Upgrade Guide][api-upgrades-guide]
outlines this process.

[compatibility-guide]: https://abseil.io/about/compatibility
[api-upgrades-guide]: https://abseil.io/docs/cpp/tools/api-upgrades
[upgrade-tools]: https://abseil.io/docs/cpp/tools/upgrades/


Status
======

[![Build Status](https://travis-ci.org/libffi/libffi.svg?branch=master)](https://travis-ci.org/libffi/libffi)
[![Build status](https://ci.appveyor.com/api/projects/status/8lko9vagbx4w2kxq?svg=true)](https://ci.appveyor.com/project/atgreen/libffi)

libffi-3.3 was released on November 23, 2019.  Check the libffi web
page for updates: <URL:http://sourceware.org/libffi/>.

What is libffi?
===============

Compilers for high level languages generate code that follow certain
conventions. These conventions are necessary, in part, for separate
compilation to work. One such convention is the "calling
convention". The "calling convention" is essentially a set of
assumptions made by the compiler about where function arguments will
be found on entry to a function. A "calling convention" also specifies
where the return value for a function is found.

Some programs may not know at the time of compilation what arguments
are to be passed to a function. For instance, an interpreter may be
told at run-time about the number and types of arguments used to call
a given function. Libffi can be used in such programs to provide a
bridge from the interpreter program to compiled code.

The libffi library provides a portable, high level programming
interface to various calling conventions. This allows a programmer to
call any function specified by a call interface description at run
time.

FFI stands for Foreign Function Interface.  A foreign function
interface is the popular name for the interface that allows code
written in one language to call code written in another language. The
libffi library really only provides the lowest, machine dependent
layer of a fully featured foreign function interface. A layer must
exist above libffi that handles type conversions for values passed
between the two languages.

Supported Platforms
===================

Libffi has been ported to many different platforms.

At the time of release, the following basic configurations have been
tested:

| Architecture    | Operating System | Compiler                |
| --------------- | ---------------- | ----------------------- |
| AArch64 (ARM64) | iOS              | Clang                   |
| AArch64         | Linux            | GCC                     |
| AArch64         | Windows          | MSVC                    |
| Alpha           | Linux            | GCC                     |
| Alpha           | Tru64            | GCC                     |
| ARC             | Linux            | GCC                     |
| ARM             | Linux            | GCC                     |
| ARM             | iOS              | GCC                     |
| ARM             | Windows          | MSVC                    |
| AVR32           | Linux            | GCC                     |
| Blackfin        | uClinux          | GCC                     |
| HPPA            | HPUX             | GCC                     |
| IA-64           | Linux            | GCC                     |
| M68K            | FreeMiNT         | GCC                     |
| M68K            | Linux            | GCC                     |
| M68K            | RTEMS            | GCC                     |
| M88K            | OpenBSD/mvme88k  | GCC                     |
| Meta            | Linux            | GCC                     |
| MicroBlaze      | Linux            | GCC                     |
| MIPS            | IRIX             | GCC                     |
| MIPS            | Linux            | GCC                     |
| MIPS            | RTEMS            | GCC                     |
| MIPS64          | Linux            | GCC                     |
| Moxie           | Bare metal       | GCC                     |
| Nios II         | Linux            | GCC                     |
| OpenRISC        | Linux            | GCC                     |
| PowerPC 32-bit  | AIX              | IBM XL C                |
| PowerPC 64-bit  | AIX              | IBM XL C                |
| PowerPC         | AMIGA            | GCC                     |
| PowerPC         | Linux            | GCC                     |
| PowerPC         | Mac OSX          | GCC                     |
| PowerPC         | FreeBSD          | GCC                     |
| PowerPC 64-bit  | FreeBSD          | GCC                     |
| PowerPC 64-bit  | Linux ELFv1      | GCC                     |
| PowerPC 64-bit  | Linux ELFv2      | GCC                     |
| RISC-V 32-bit   | Linux            | GCC                     |
| RISC-V 64-bit   | Linux            | GCC                     |
| S390            | Linux            | GCC                     |
| S390X           | Linux            | GCC                     |
| SPARC           | Linux            | GCC                     |
| SPARC           | Solaris          | GCC                     |
| SPARC           | Solaris          | Oracle Solaris Studio C |
| SPARC64         | Linux            | GCC                     |
| SPARC64         | FreeBSD          | GCC                     |
| SPARC64         | Solaris          | Oracle Solaris Studio C |
| TILE-Gx/TILEPro | Linux            | GCC                     |
| VAX             | OpenBSD/vax      | GCC                     |
| X86             | FreeBSD          | GCC                     |
| X86             | GNU HURD         | GCC                     |
| X86             | Interix          | GCC                     |
| X86             | kFreeBSD         | GCC                     |
| X86             | Linux            | GCC                     |
| X86             | Mac OSX          | GCC                     |
| X86             | OpenBSD          | GCC                     |
| X86             | OS/2             | GCC                     |
| X86             | Solaris          | GCC                     |
| X86             | Solaris          | Oracle Solaris Studio C |
| X86             | Windows/Cygwin   | GCC                     |
| X86             | Windows/MingW    | GCC                     |
| X86-64          | FreeBSD          | GCC                     |
| X86-64          | Linux            | GCC                     |
| X86-64          | Linux/x32        | GCC                     |
| X86-64          | OpenBSD          | GCC                     |
| X86-64          | Solaris          | Oracle Solaris Studio C |
| X86-64          | Windows/Cygwin   | GCC                     |
| X86-64          | Windows/MingW    | GCC                     |
| X86-64          | Mac OSX          | GCC                     |
| Xtensa          | Linux            | GCC                     |

Please send additional platform test results to
libffi-discuss@sourceware.org.

Installing libffi
=================

First you must configure the distribution for your particular
system. Go to the directory you wish to build libffi in and run the
"configure" program found in the root directory of the libffi source
distribution.  Note that building libffi requires a C99 compatible
compiler.

If you're building libffi directly from git hosted sources, configure
won't exist yet; run ./autogen.sh first.  This will require that you
install autoconf, automake and libtool.

You may want to tell configure where to install the libffi library and
header files. To do that, use the ``--prefix`` configure switch.  Libffi
will install under /usr/local by default.

If you want to enable extra run-time debugging checks use the the
``--enable-debug`` configure switch. This is useful when your program dies
mysteriously while using libffi.

Another useful configure switch is ``--enable-purify-safety``. Using this
will add some extra code which will suppress certain warnings when you
are using Purify with libffi. Only use this switch when using
Purify, as it will slow down the library.

If you don't want to build documentation, use the ``--disable-docs``
configure switch.

It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler.  In this case, use the msvcc.sh
wrapper script during configuration like so:

    path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP" CPPFLAGS="-DFFI_BUILDING_DLL"

For 64-bit Windows builds, use ``CC="path/to/msvcc.sh -m64"`` and
``CXX="path/to/msvcc.sh -m64"``.  You may also need to specify
``--build`` appropriately.

It is also possible to build libffi on Windows platforms with the LLVM
project's clang-cl compiler, like below:

    path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP"

When building with MSVC under a MingW environment, you may need to
remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
command.  ('cygpath' is not present in MingW, and is not required when
using MingW-style paths.)

To build static library for ARM64 with MSVC using visual studio solution, msvc_build folder have
   aarch64/Ffi_staticLib.sln
   required header files in aarch64/aarch64_include/

SPARC Solaris builds require the use of the GNU assembler and linker.
Point ``AS`` and ``LD`` environment variables at those tool prior to
configuration.

For iOS builds, the ``libffi.xcodeproj`` Xcode project is available.

Configure has many other options. Use ``configure --help`` to see them all.

Once configure has finished, type "make". Note that you must be using
GNU make.  You can ftp GNU make from ftp.gnu.org:/pub/gnu/make .

To ensure that libffi is working as advertised, type "make check".
This will require that you have DejaGNU installed.

To install the library and header files, type ``make install``.

History
=======

See the git log for details at http://github.com/libffi/libffi.

    3.3 Nov-23-19
        Add RISC-V support.
        New API in support of GO closures.
        Add IEEE754 binary128 long double support for 64-bit Power
        Default to Microsoft's 64 bit long double ABI with Visual C++.
        GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
        Add Windows on ARM64 (WOA) support.
        Add Windows 32-bit ARM support.
        Raw java (gcj) API deprecated.
	Add pre-built PDF documentation to source distribution.
        Many new tests cases and bug fixes.

    3.2.1 Nov-12-14
        Build fix for non-iOS AArch64 targets.

    3.2 Nov-11-14
        Add C99 Complex Type support (currently only supported on
          s390).
        Add support for PASCAL and REGISTER calling conventions on x86
          Windows/Linux.
        Add OpenRISC and Cygwin-64 support.
        Bug fixes.

    3.1 May-19-14
        Add AArch64 (ARM64) iOS support.
        Add Nios II support.
        Add m88k and DEC VAX support.
        Add support for stdcall, thiscall, and fastcall on non-Windows
          32-bit x86 targets such as Linux.
        Various Android, MIPS N32, x86, FreeBSD and UltraSPARC IIi
          fixes.
        Make the testsuite more robust: eliminate several spurious
          failures, and respect the $CC and $CXX environment variables.
        Archive off the manually maintained ChangeLog in favor of git
          log.

    3.0.13 Mar-17-13
        Add Meta support.
        Add missing Moxie bits.
        Fix stack alignment bug on 32-bit x86.
        Build fix for m68000 targets.
        Build fix for soft-float Power targets.
        Fix the install dir location for some platforms when building
          with GCC (OS X, Solaris).
        Fix Cygwin regression.

    3.0.12 Feb-11-13
        Add Moxie support.
        Add AArch64 support.
        Add Blackfin support.
        Add TILE-Gx/TILEPro support.
        Add MicroBlaze support.
        Add Xtensa support.
        Add support for PaX enabled kernels with MPROTECT.
        Add support for native vendor compilers on
          Solaris and AIX.
        Work around LLVM/GCC interoperability issue on x86_64.

    3.0.11 Apr-11-12
        Lots of build fixes.
        Add support for variadic functions (ffi_prep_cif_var).
        Add Linux/x32 support.
        Add thiscall, fastcall and MSVC cdecl support on Windows.
        Add Amiga and newer MacOS support.
        Add m68k FreeMiNT support.
        Integration with iOS' xcode build tools.
        Fix Octeon and MC68881 support.
        Fix code pessimizations.

    3.0.10 Aug-23-11
        Add support for Apple's iOS.
        Add support for ARM VFP ABI.
        Add RTEMS support for MIPS and M68K.
        Fix instruction cache clearing problems on
          ARM and SPARC.
        Fix the N64 build on mips-sgi-irix6.5.
        Enable builds with Microsoft's compiler.
        Enable x86 builds with Oracle's Solaris compiler.
        Fix support for calling code compiled with Oracle's Sparc
          Solaris compiler.
        Testsuite fixes for Tru64 Unix.
        Additional platform support.

    3.0.9 Dec-31-09
        Add AVR32 and win64 ports.  Add ARM softfp support.
        Many fixes for AIX, Solaris, HP-UX, *BSD.
        Several PowerPC and x86-64 bug fixes.
        Build DLL for windows.

    3.0.8 Dec-19-08
        Add *BSD, BeOS, and PA-Linux support.

    3.0.7 Nov-11-08
        Fix for ppc FreeBSD.
        (thanks to Andreas Tobler)

    3.0.6 Jul-17-08
        Fix for closures on sh.
        Mark the sh/sh64 stack as non-executable.
        (both thanks to Kaz Kojima)

    3.0.5 Apr-3-08
        Fix libffi.pc file.
        Fix #define ARM for IcedTea users.
        Fix x86 closure bug.

    3.0.4 Feb-24-08
        Fix x86 OpenBSD configury.

    3.0.3 Feb-22-08
        Enable x86 OpenBSD thanks to Thomas Heller, and
          x86-64 FreeBSD thanks to Björn König and Andreas Tobler.
        Clean up test instruction in README.

    3.0.2 Feb-21-08
        Improved x86 FreeBSD support.
        Thanks to Björn König.

    3.0.1 Feb-15-08
        Fix instruction cache flushing bug on MIPS.
        Thanks to David Daney.

    3.0.0 Feb-15-08
        Many changes, mostly thanks to the GCC project.
        Cygnus Solutions is now Red Hat.

      [10 years go by...]

    1.20 Oct-5-98
        Raffaele Sena produces ARM port.

    1.19 Oct-5-98
        Fixed x86 long double and long long return support.
        m68k bug fixes from Andreas Schwab.
        Patch for DU assembler compatibility for the Alpha from Richard
          Henderson.

    1.18 Apr-17-98
        Bug fixes and MIPS configuration changes.

    1.17 Feb-24-98
        Bug fixes and m68k port from Andreas Schwab. PowerPC port from
        Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.

    1.16 Feb-11-98
        Richard Henderson produces Alpha port.

    1.15 Dec-4-97
        Fixed an n32 ABI bug. New libtool, auto* support.

    1.14 May-13-97
        libtool is now used to generate shared and static libraries.
        Fixed a minor portability problem reported by Russ McManus
        <mcmanr@eq.gs.com>.

    1.13 Dec-2-96
        Added --enable-purify-safety to keep Purify from complaining
          about certain low level code.
        Sparc fix for calling functions with < 6 args.
        Linux x86 a.out fix.

    1.12 Nov-22-96
        Added missing ffi_type_void, needed for supporting void return
          types. Fixed test case for non MIPS machines. Cygnus Support
          is now Cygnus Solutions.

    1.11 Oct-30-96
        Added notes about GNU make.

    1.10 Oct-29-96
        Added configuration fix for non GNU compilers.

    1.09 Oct-29-96
        Added --enable-debug configure switch. Clean-ups based on LCLint
        feedback. ffi_mips.h is always installed. Many configuration
        fixes. Fixed ffitest.c for sparc builds.

    1.08 Oct-15-96
        Fixed n32 problem. Many clean-ups.

    1.07 Oct-14-96
        Gordon Irlam rewrites v8.S again. Bug fixes.

    1.06 Oct-14-96
        Gordon Irlam improved the sparc port.

    1.05 Oct-14-96
        Interface changes based on feedback.

    1.04 Oct-11-96
        Sparc port complete (modulo struct passing bug).

    1.03 Oct-10-96
        Passing struct args, and returning struct values works for
        all architectures/calling conventions. Expanded tests.

    1.02 Oct-9-96
        Added SGI n32 support. Fixed bugs in both o32 and Linux support.
        Added "make test".

    1.01 Oct-8-96
        Fixed float passing bug in mips version. Restructured some
        of the code. Builds cleanly with SGI tools.

    1.00 Oct-7-96
        First release. No public announcement.

Authors & Credits
=================

libffi was originally written by Anthony Green <green@moxielogic.com>.

The developers of the GNU Compiler Collection project have made
innumerable valuable contributions.  See the ChangeLog file for
details.

Some of the ideas behind libffi were inspired by Gianni Mariani's free
gencall library for Silicon Graphics machines.

The closure mechanism was designed and implemented by Kresten Krab
Thorup.

Major processor architecture ports were contributed by the following
developers:

    aarch64             Marcus Shawcroft, James Greenhalgh
    alpha               Richard Henderson
    arc                 Hackers at Synopsis
    arm                 Raffaele Sena
    avr32               Bradley Smith
    blackfin            Alexandre Keunecke I. de Mendonca
    cris                Simon Posnjak, Hans-Peter Nilsson
    frv                 Anthony Green
    ia64                Hans Boehm
    m32r                Kazuhiro Inaoka
    m68k                Andreas Schwab
    m88k                Miod Vallat
    metag               Hackers at Imagination Technologies
    microblaze          Nathan Rossi
    mips                Anthony Green, Casey Marshall
    mips64              David Daney
    moxie               Anthony Green
    nios ii             Sandra Loosemore
    openrisc            Sebastian Macke
    pa                  Randolph Chung, Dave Anglin, Andreas Tobler
    powerpc             Geoffrey Keating, Andreas Tobler,
                        David Edelsohn, John Hornkvist
    powerpc64           Jakub Jelinek
    riscv               Michael Knyszek, Andrew Waterman, Stef O'Rear
    s390                Gerhard Tonn, Ulrich Weigand
    sh                  Kaz Kojima
    sh64                Kaz Kojima
    sparc               Anthony Green, Gordon Irlam
    tile-gx/tilepro     Walter Lee
    vax                 Miod Vallat
    x86                 Anthony Green, Jon Beniston
    x86-64              Bo Thorsen
    xtensa              Chris Zankel

Jesper Skov and Andrew Haley both did more than their fair share of
stepping through the code and tracking down bugs.

Thanks also to Tom Tromey for bug fixes, documentation and
configuration help.

Thanks to Jim Blandy, who provided some useful feedback on the libffi
interface.

Andreas Tobler has done a tremendous amount of work on the testsuite.

Alex Oliva solved the executable page problem for SElinux.

The list above is almost certainly incomplete and inaccurate.  I'm
happy to make corrections or additions upon request.

If you have a problem, or have found a bug, please send a note to the
author at green@moxielogic.com, or the project mailing list at
libffi-discuss@sourceware.org.